Page 1 of 2 12 LastLast
Results 1 to 10 of 19

Thread: Struts 2 Integration with Spring DM

  1. #1
    Join Date
    Jul 2006
    Posts
    126

    Default Struts 2 Integration with Spring DM

    Hi,

    Our application is based on struts2 and spring. We have a need to deploy the application in OSGI environment. I have succeeded in migrating the spring layered components (services) to the OSGI environment, however I am not sure how to transform struts2 components (action handlers) to the OSGI environment.

    I have read about struts2-osgi plugin however it works on deployment of the web application inside the servlet container and embedding the osgi container within the servlet container. However I am looking for a solution wherein I can deploy the struts action bundles within the OSGI container along with the servlet container bundle.

    Please let me know of any pointer you have.

    Thanks in advance,
    Shashi

  2. #2
    Join Date
    Jul 2006
    Posts
    126

    Default

    Hi,

    Could somebody please share the thoughts on this?

    I am able to exchange few emails with Don Brown (author of Struts2-OSGi plugin). He has mentioned to use extender pattern in OSGi, the way it is implemented in Spring OSGi Extender.

    However I am not clear on how to achieve this.
    I can think of the following bundles and their interaction.

    The OSGi container is going to host following bundles
    1) Struts2
    2) xwork
    3) Spring DMs
    4) Web container module
    5) Extender bundle for loading the struts action bundles(I am going to code for this)
    6) Struts action bundles developed for the application (application developers are going to code these)

    The extender bundle is going to load the struts configurations from the respective action bundle, however after loading the configurations, what should the extender do? Can it expose the packages it gets as OSGi services? If so, who will consume these services? The struts2-core bundle would require these action to serve the requests from the browser, however to obtain the exposed OSGi actions I need to change struts2 code. Does this sound like a good idea?

    Please share your thoughts.

    Thanks in advance,
    Shashi

  3. #3
    Join Date
    Jan 2005
    Location
    Bucharest, Romania
    Posts
    5,403

    Default

    Shashi, from what I understand you want to host both the web container and struts inside OSGi. Spring DM took this approach for its web integration where the web container is exposed as a service which is then used for deploying wars.
    The war is doing the classloading from the OSGi space so whatever libraries it imports, are used by the war.
    You could do the same thing in your case - create a war with some basic struts2/webwork functionality and deploy that into OSGi along with struts 2 and Spring DM and the container of your choice (see the Spring DM reference documentation).

    From that point on you can identify what packages are needed and whether you have any resource or classloading issues from Struts2.
    Costin Leau
    SpringSource - http://www.SpringSource.com- Spring Training, Consulting, and Support - "From the Source"
    http://twitter.com/costinl
    Please use [ c o d e ] [ / c o d e ] tags

  4. #4
    Join Date
    Jul 2006
    Posts
    126

    Default

    Thanks Costin.

    I am following your idea of making the war module independently work with struts2 and webwork.

    In fact the war is getting deployed fine. Now there is another issue which is again basic OSGi classloading problem I am encountering.

    Let me explain what is the structure of the modules in the equinox environment.
    I have following modules deployed
    1) Spring DMs
    2) Struts2
    3) xwork
    4) action bundle (This has actions required for the application)
    5) web bundle (I had to copy struts2, xwork and struts2-extender in the web-inf/lib and add these jars to the classpath dependency of the web module to make struts filter dispatcher work and dynamically load action modules)

    The struts2-extender jar is the struts2-osgi plugin which I modified a bit so that it can work within the web module. This plugin would load the configurations from the action bundles getting plugged into the container.
    However here I am facing NoClassDefFoundError for struts and xwork related classes. I have added the dependency for these bundles in the web bundle as well as action bundle. The same error persists.

    HTML Code:
    Caused by: java.lang.NoClassDefFoundError: com/opensymphony/xwork2/interceptor/Interceptor
    	at java.lang.ClassLoader.defineClass1(Native Method)
    	at java.lang.ClassLoader.defineClass(ClassLoader.java:620)
    	at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.defineClass(DefaultClassLoader.java:161)
    	at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.defineClass(ClasspathManager.java:501)
    	at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findClassImpl(ClasspathManager.java:471)
    	at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findLocalClassImpl(ClasspathManager.java:430)
    	at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findLocalClass(ClasspathManager.java:413)
    	at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.findLocalClass(DefaultClassLoader.java:189)
    	at org.eclipse.osgi.framework.internal.core.BundleLoader.findLocalClass(BundleLoader.java:340)
    	at org.eclipse.osgi.framework.internal.core.BundleLoader.findClassInternal(BundleLoader.java:408)
    	at org.eclipse.osgi.framework.internal.core.BundleLoader.findClass(BundleLoader.java:369)
    	at org.eclipse.osgi.framework.internal.core.BundleLoader.findClass(BundleLoader.java:357)
    	at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:83)
    	at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
    	at org.eclipse.osgi.framework.internal.core.BundleLoader.loadClass(BundleLoader.java:289)
    	at org.eclipse.osgi.framework.internal.core.BundleHost.loadClass(BundleHost.java:227)
    	at org.eclipse.osgi.framework.internal.core.AbstractBundle.loadClass(AbstractBundle.java:1269)
    	at org.apache.struts2.osgi.DefaultBundleAccessor.loadClass(DefaultBundleAccessor.java:109)
    	at org.apache.struts2.osgi.DelegatingObjectFactory.buildBean(DelegatingObjectFactory.java:64)
    	at com.opensymphony.xwork2.ObjectFactory.buildBean(ObjectFactory.java:139)
    	at com.opensymphony.xwork2.ObjectFactory.buildInterceptor(ObjectFactory.java:180)
    	... 31 more
    I am going to try few more things like adding other bundles on which com/opensymphony/xwork2/interceptor/Interceptor could be dependent on.

    Please let me know of any other solution you may have.

    Thanks for your help,
    Shashi

  5. #5
    Join Date
    Jul 2006
    Posts
    126

    Default

    Hi,

    I have tried putting the dependencies on which the com/opensymphony/xwork2/interceptor/Interceptor was dependent on but with no success

    Please let me know of any other solution you may have.

    Thanks,
    Shashi

  6. #6
    Join Date
    Jan 2005
    Location
    Bucharest, Romania
    Posts
    5,403

    Default

    I think the easiest way to get to the bottom of this is to d/l the Struts 2 sources and see what code is executed when the exception occurs. You can find information about what class loader is used and potentially change it to one that sees your classes.
    For example if the TCCL is used, then you can adjust it to a correct value, right before your app is started.

    In other news, you can give dmServer a try - it is based on Spring DM and Spring but it handles runtime issues (like the ones you've discovered above).
    Costin Leau
    SpringSource - http://www.SpringSource.com- Spring Training, Consulting, and Support - "From the Source"
    http://twitter.com/costinl
    Please use [ c o d e ] [ / c o d e ] tags

  7. #7
    Join Date
    Jul 2006
    Posts
    126

    Default

    Thanks Costin,

    I am trying to debug the struts2 code. Actually this is the struts2 plugin code which is getting executed when the war bundle is loaded. I have pasted it below.

    Code:
        public Class<?> loadClass(String className) throws ClassNotFoundException {
            Bundle bundle = getCurrentBundle(); //Line 1
            if (bundle != null) {            
            	Class cls = bundle.loadClass(className); //Line2
                if (LOG.isTraceEnabled())
                    LOG.trace("Located class [#0] in bundle [#1]", className, bundle.getSymbolicName());
                return cls;
            }
    
            throw new ClassNotFoundException("Unable to find class " + className);
        }
    At line1 the action bundle is obtained. This is the bundle where application action/interceptor classes are bundled. The bundle obtained is fine which I can see in the debugging session. However when it enters the if condition where at Line2 it tries to load the interceptor/action class (which is dependent the packages in struts and xwork bundles), the exception is thrown. To do further debugging I wrote a test activator class where I try to load a Struts class, however this fails as well.

    Could there be any other reason which would be causing the problem to load struts or xwork classes?

    Further I am going to do further investigation in terms of the classloader related inputs you have provided.

    Please let me know any other input you may have.

    Thanks,
    Shashi

  8. #8
    Join Date
    Jul 2006
    Posts
    126

    Default

    Hi,

    I could resolve the NoClassDefFoundError. The problem was with the struts2 and xwork bundles I was deploying in the OSGi container. These bundles were not visible inside any other bundle. So I replaced these bundles from the nighly builds available at apache struts site.

    Now the struts and xwork classes are visible to the classloader. However now I have landed into another problem.

    In my war bundle I have
    1) struts jar
    2) xwork jar
    3) struts-extender jar (This is the modified version of the struts-osgi plugin)

    The struts-extender tries to load the struts related configurations from the other application action bundles deployed in the OSGi container.

    Now the application action bundles are dependent on the struts and xwork BUNDLES deployed in the container. Please note that these are separately deployed bundles and not related to the jars in the web application. Hence the instance of action or interceptor created out of the action bundle is dependent on the xwork/struts bundle classes. Hence the struts/xwork jars contained inside the war bundle throw classcastexcetion saying that the interceptor defined in application action bundle does not implement Interceptor class.

    HTML Code:
    Class [com.arisglobal.aglite.ui.interceptors.ExceptionInterceptor] does not implement com.opensymphony.xwork2.interceptor.Interceptor - interceptor - bundleresource://41/struts.xml:33:74
    	at com.opensymphony.xwork2.ObjectFactory.buildInterceptor(ObjectFactory.java:202)
    	at com.opensymphony.xwork2.config.providers.InterceptorBuilder.constructInterceptorReference(InterceptorBuilder.java:59)
    	at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.lookupInterceptorReference(XmlConfigurationProvider.java:987)
    	at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.loadInterceptorStack(XmlConfigurationProvider.java:806)
    	at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.loadInterceptorStacks(XmlConfigurationProvider.java:819)
    	at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.loadInterceptors(XmlConfigurationProvider.java:842)
    	at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.addPackage(XmlConfigurationProvider.java:449)
    	at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.loadPackages(XmlConfigurationProvider.java:264)
    	at org.apache.struts2.osgi.BundlePackageLoader.loadPackages(BundlePackageLoader.java:58)
    	at org.apache.struts2.osgi.OsgiConfigurationProvider.loadConfigFromBundle(OsgiConfigurationProvider.java:133)
    	at org.apache.struts2.osgi.OsgiConfigurationProvider.loadPackages(OsgiConfigurationProvider.java:98)
    	at com.opensymphony.xwork2.config.impl.DefaultConfiguration.reloadContainer(DefaultConfiguration.java:204)
    	at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:55)
    	at org.apache.struts2.dispatcher.Dispatcher.init_PreloadConfiguration(Dispatcher.java:364)
    	at org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:408)
    	at org.apache.struts2.dispatcher.FilterDispatcher.init(FilterDispatcher.java:190)
    	at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:275)
    	at org.apache.catalina.core.ApplicationFilterConfig.setFilterDef(ApplicationFilterConfig.java:397)
    	at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:108)
    	at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:3709)
    	at org.apache.catalina.core.StandardContext.start(StandardContext.java:4363)
    	at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:791)
    	at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:771)
    	at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:525)
    	at org.springframework.osgi.web.deployer.tomcat.TomcatWarDeployer.startCatalinaContext(TomcatWarDeployer.java:144)
    	at org.springframework.osgi.web.deployer.tomcat.TomcatWarDeployer.startDeployment(TomcatWarDeployer.java:133)
    	at org.springframework.osgi.web.deployer.support.AbstractWarDeployer.deploy(AbstractWarDeployer.java:93)
    	at org.springframework.osgi.web.extender.internal.activator.WarLoaderListener$DeploymentManager$DeployTask.doRun(WarLoaderListener.java:247)
    	at org.springframework.osgi.web.extender.internal.activator.WarLoaderListener$DeploymentManager$BaseTask.run(WarLoaderListener.java:219)
    	at org.springframework.scheduling.timer.DelegatingTimerTask.run(DelegatingTimerTask.java:66)
    	at java.util.TimerThread.mainLoop(Timer.java:512)
    	at java.util.TimerThread.run(Timer.java:462)
    Caused by: java.lang.ClassCastException: com.arisglobal.aglite.ui.interceptors.ExceptionInterceptor
    	at com.opensymphony.xwork2.ObjectFactory.buildInterceptor(ObjectFactory.java:180)
    	... 31 more
    I am out of clues to solve this issue.

    Can you pass any help you may have.

    Thanks in advance,
    Shashi

  9. #9
    Join Date
    Jan 2005
    Location
    Bucharest, Romania
    Posts
    5,403

    Default

    So if I understand correctly, you have two versions - one outside OSGi and one inside? If it is so, then you can go around it by bootdelegating the classes so that the OSGi platform actually loads the classes from the libraries deployed inside the container.
    This has some downsides however.
    There is a blog by yours truly on bootpath delegation which might be helpful, if you're interested in the topic.
    Costin Leau
    SpringSource - http://www.SpringSource.com- Spring Training, Consulting, and Support - "From the Source"
    http://twitter.com/costinl
    Please use [ c o d e ] [ / c o d e ] tags

  10. #10
    Join Date
    Jul 2006
    Posts
    126

    Default

    Hi Costin,

    Thanks.

    Yes, I have two versions of the same jars. One set is within the web bundle as normal jars and the other set is deployed as bundles.

    I am going to go through your blog and would certainly give a try to your solution of bootpath delegation. However I have an initial question here. For loading the struts configuration without problems I think I would need struts and xwork jars within the web bundle. Otherwise I would end in the problem which we are discussing at http://forum.springsource.org/showthread.php?t=68941. IMHO setting these jars as part of the bootpath would still create the Malformed URL issue which I have posted. Please share your opinion.

    This may sound stupid, but I am not able to use bootdelegation in equinox launcher within eclipse. I have set
    HTML Code:
    -Dorg.osgi.framework.bootdelegation=com.opensymphony.*,org.apache.struts2.*
    in the arguments tab of the equinox run setup. Also the plugin target platform contain both xwork and struts2 bundles. However after removing the struts and xwork jars from the web module I get CNFE for
    HTML Code:
    java.lang.ClassNotFoundException: org.apache.struts2.dispatcher.FilterDispatcher
    	at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
    	at java.security.AccessController.doPrivileged(Native Method)
    Could you please point me to some tutorial or reference on this?

    Thanks for your help,
    Shashi
    Last edited by shashi; Jun 1st, 2009 at 11:40 AM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •