You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 34 Next »

Name

OSGi Plugin

Publisher

Donald Brown

License

Open Source (ASL2)

Version

0.1-SNAPSHOT

Compatibility

Struts 2.0.9+

Homepage

OSGi Plugin

Experimental

Yes

Download

SVN

Error formatting macro: rate: java.lang.NoSuchMethodError: 'java.lang.String com.atlassian.confluence.setup.BootstrapManager.getDomainName()'

Overview

This plugin is only experimental and hasn't been released yet. It is not ready to be used in production applications.

Features

  • GUI for bundle administration
  • Web access to Felix Shell
  • Application packages can be divided into bundles
  • Supports Velocity and FreeMarker templates
  • Supports Struts Spring integration
  • Supports integration with the Convention plugin

Missing Features

  • Probably can't access application classes from bundles, including Spring classes
  • If Spring is used in the bundles, then it cannot (yet) be used in the web application

About Run levels

Application bundles should go under /WEB-INF/classes/bundles. Bundles in this dir will be started in run level 2, the Apache Felix framework's bundles will be loaded in run level 1. Any other bundle under /WEB-INF/classes/bundles/other will be started in run level 3.

Simple Usage

Add these lines to MANIFEST.MF:

Bundle-Activator: org.apache.struts2.osgi.StrutsActivator
Export-Package: com.mycompany.myapp.actions
Bundle-Version: 1.0.0
Bundle-SymbolicName: foo.actions
Import-Package: com.opensymphony.xwork2

Now the jar is ready to be deployed. Drop the jar into the /WEB-INF/classes/bundles directory and it will automatically be installed when the application starts up.

Using Spring

By default Spring OSGi loads its xml config files asynchronously, which causes the OSGi plugin to fail while starting. To fix this add this line to MANIFEST.MF:

Spring-Context:*;create-asynchronously:=false

Or if using The Apache Felix maven plugin (see below for details):

<Spring-Context>*;create-asynchronously:=false</Spring-Context>

If you want to use the Spring as the object factory for your actions, then follow these steps:

  1. Place your Spring xml files under /META-INF/spring in the bundle jar file
  2. Copy all the bundle jar files into /WEB-INF/classes/bundles in your application
  3. Make sure that the following properties are set in struts.xml or struts.properties in your application:
    <constant name="struts.objectFactory" value="osgi" />
    <constant name="struts.objectFactory.delegate" value="springOsgi" />
    <constant name="struts.freemarker.manager.classname" value="org.apache.struts2.osgi.BundleFreemarkerManager" />
    
  4. Install the Struts 2 Spring plugin in your application, like in normal Struts 2 applications.
  5. Configure your web.xml like:
        <?xml version="1.0" encoding="UTF-8"?>
    <web-app id="WebApp_9" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
        <display-name>Struts Blank</display-name>
    
        <filter>
            <filter-name>struts2-execute</filter-name>
            <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsExecuteFilter</filter-class>
        </filter>
    
        <filter>
            <filter-name>struts2-prepare</filter-name>
            <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareFilter</filter-class>
        </filter>
    
        <filter-mapping>
            <filter-name>struts2-prepare</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
    
        <filter-mapping>
            <filter-name>struts2-execute</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
    
        <listener>
            <listener-class>org.apache.struts2.dispatcher.ng.listener.StrutsListener</listener-class>
        </listener>
    
        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
    
        <context-param>
            <param-name>contextClass</param-name>
            <param-value>org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext</param-value>
        </context-param>
        <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>osgibundle:/META-INF/spring/*.xml</param-value>
        </context-param>
    </web-app>
    
  1. Add the Spring OSGi dependency to your web app, if you are using maven:
    <dependency>
         <groupId>org.springframework.osgi</groupId>
         <artifactId>spring-osgi-web</artifactId>
         <version>1.1.2</version>
    </dependency>
    
  2. Download Spring OSGi and copy all the required bundles under /classes/bundles/other. For Struts OSGi 1.1.2, these are the required bundles:
    com.springsource.org.aopalliance-1.0.0.jar
    com.springsource.org.apache.commons.logging-1.1.1.jar
    org.springframework.aop-2.5.5.A.jar
    org.springframework.beans-2.5.5.A.jar
    org.springframework.context-2.5.5.A.jar
    org.springframework.core-2.5.5.A.jar
    org.springframework.osgi.core-1.1.2.A.jar
    org.springframework.osgi.extender-1.1.2.A.jar
    org.springframework.osgi.io-1.1.2.A.jar
    org.springframework.osgi.web-1.1.2.A.jar
    org.springframework.web-2.5.5.A.jar
    

Using Velocity

If you are going to use Velocity results, then add Velocity and Common Digester jars to your application. Using maven:

<dependency>
    <groupId>velocity</groupId>
    <artifactId>velocity</artifactId>
    <version>1.5</version>
</dependency>

<dependency>
    <groupId>velocity-tools</groupId>
    <artifactId>velocity-tools</artifactId>
    <version>1.3</version>
</dependency>

<dependency>
    <groupId>commons-digester</groupId>
    <artifactId>commons-digester</artifactId>
    <version>1.8</version>
</dependency>

Using The Convention Plugin

The Convention plugin will discover actions in bundles in the same way that it discovers them in normal applications. The Convention plugin expects result templates to be (by default) stored under /WEB-INF/content. When packaging actions inside bundles, there won't be a WEB-INF folder, so you must let Convention know where the templates are located. There are two ways of doing so(assuming the templates are under /content):

1. Set the templates location constant in struts.xml (in the application struts.xml, not a bundled struts.xml)

<constant name="struts.convention.result.path" value="/content/"/>

2. Using the ResultPath annotation

@ResultPath("/content")
public class HelloWorldAction extends ActionSupport
...
}

Settings

The following settings can be customized. See the developer guide.

Setting

Description

Default

Possible Values

struts.objectFactory.delegate

The alias of the ObjectFactory to wrap

struts

Any configured alias

struts.osgi.clearBundleCache

Delete all installed bundles when the container starts

 

true or false

struts.osgi.clearBundleCache

Run level to start the container

3

>=3

Building bundles with Maven

See the Maven Bundle Plugin documentation for more details.

Example
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.felix</groupId>
            <artifactId>maven-bundle-plugin</artifactId>
            <extensions>true</extensions>
            <version>2.0.0</version>
            <configuration>
                <instructions>
                    <manifestLocation>META-INF</manifestLocation>
                    <Export-Package>org.apache.struts2.osgi.demo</Export-Package>
                    <Import-Package>*,com.opensymphony.xwork2</Import-Package>
                    <Bundle-Activator>org.apache.struts2.osgi.StrutsActivator</Bundle-Activator>
                    <Spring-Context>*;create-asynchronously:=false</Spring-Context>
                </instructions>
            </configuration>
        </plugin>
    </plugins>
</build>

Resources

Version History

Version

Date

Author

Notes

  • No labels