サンプル

https://github.com/kagyuu/OSGiExam

OSGiとは?

OSGiアプリケーションのベスト・プラクティス

開発環境 (Maven Multi-module)

  1. [新規]-[Maven]-[POMプロジェクト]
    parent1.png
  2. こんなプロジェクトができる
    parent2.png
  3. pom.xml に、配下の Module で共通的に使われるライブラリを定義する
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.mycompany</groupId>
        <artifactId>OSGiExam</artifactId>
        <version>1.0-SNAPSHOT</version>
        <packaging>pom</packaging>
        <name>OSGiExam</name>
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.osgi</groupId>
                    <artifactId>org.osgi.core</artifactId>
                    <version>4.2.0</version>
                    <scope>provided</scope>
                </dependency>
                <dependency>
                    <groupId>org.glassfish</groupId>
                    <artifactId>osgi-cdi-api</artifactId>
                    <version>3.1</version>
                    <scope>provided</scope>
                </dependency>
                <!-- It's not javaee-api, because we want to test business logic -->
                <dependency>
                    <groupId>org.glassfish.main.extras</groupId>
                    <artifactId>glassfish-embedded-all</artifactId>
                    <version>3.1.2.2</version>
                    <scope>provided</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>  
        <repositories>
            <!-- glassfish nexus repo for glassfish dependencies -->
            <repository>
                <id>glassfish-repo-archive</id>
                <name>Nexus repository collection for Glassfish</name>
                <url>http://maven.glassfish.org/content/groups/glassfish</url>
                <snapshots>
                    <updatePolicy>never</updatePolicy>
                </snapshots>
            </repository>
        </repositories>  
    </project>
    

API バンドルを作る

  1. [新規]-[Maven]-[OSGiバンドル]
    api1.png
  2. 作成場所を OSGiExam? の直下にする
    api2.png
  3. 自動的に OSGiExamApi? は、OSGiExam? のモジュールになった
    api3.png
    OSGiExam?/pom.xml には、配下のモジュール定義が追加されている
        </repositories>  
      <modules>
        <module>OSGiExamApi</module>
      </modules>
    </project>
  4. OSGiExam?/OSGiExamApi?/pom.xml を編集して、親プロジェクト (OSGiExam?) の pom.xml のライブラリ参照定義を継承する。(GUI からやりたければ、ソースツリーの [依存性] を右クリックして、[依存性の追加]-[依存性管理] で、親プロジェクトの管理しているライブラリを追加できる)
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
        <artifactId>OSGiExam</artifactId>
        <groupId>com.mycompany</groupId>
        <version>1.0-SNAPSHOT</version>
        </parent>
    
        <groupId>com.mycompany</groupId>
        <artifactId>OSGiExamApi</artifactId>
        <version>1.0-SNAPSHOT</version>
        <packaging>bundle</packaging>
    
        <name>OSGiExamApi OSGi Bundle</name>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.osgi</groupId>
                <artifactId>org.osgi.core</artifactId>
            </dependency>
            <dependency>
                <groupId>org.glassfish.main.extras</groupId>
                <artifactId>glassfish-embedded-all</artifactId>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                ...
    
  5. インタフェースを作成 (POJO用)
    package com.mycompany.osgiexamapi;
    
    public interface Hello {
        String sayHello(String name);
    }
    
  6. インタフェースを作成 (EJB用)
    package com.mycompany.osgiexamapi;
    
    import javax.ejb.Local;
    
    @Local
    public interface GoodBye {
        String sayGoodBye(String name);
    }
    
  7. ほかのバンドルから参照できる、このバンドルの公開パッケージの設定。(GUI からやりたければ、ソースツリーの [OSGiExamApi?] を右クリックして、[プロパティ]-[パッケージをエクスポート] で、親プロジェクトの管理しているライブラリを追加できる)
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
        <artifactId>OSGiExam</artifactId>
        <groupId>com.mycompany</groupId>
        <version>1.0-SNAPSHOT</version>
        </parent>
        ...
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.felix</groupId>
                    <artifactId>maven-bundle-plugin</artifactId>
                    <version>2.3.7</version>
                    <extensions>true</extensions>
                    <configuration>
                        <instructions>
                            <Bundle-Activator>com.mycompany.osgiexamapi.Activator</Bundle-Activator>
                            <Export-Package >com.mycompany.osgiexamapi</Export-Package>
                            <Private-Package>com.mycompany.osgiexamapi.*</Private-Package>
                        </instructions>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    
  8. [実行]-[ビルド] で、バンドルができる。バンドルと言っても、普通の Jar。MANIFEST.MF ファイルに追加の記述があるだけ。MANIFEST.MF は、pom.xml に定義された maven-bundle-plugin がビルド時に作成する。
    api4.png

テスト用の Web アプリを作る

  1. プロジェクトを作成
    web1.png
    /OSGiExam? 配下にモジュールとして Web アプリを作る (OSGiExam?/OSGiExamWeb? に作成)
  2. 依存ライブラリの設定 (親プロジェクト (OSGiExam?) と APIを参照する)
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
        <artifactId>OSGiExam</artifactId>
        <groupId>com.mycompany</groupId>
        <version>1.0-SNAPSHOT</version>
      </parent>
    
        <groupId>com.mycompany</groupId>
        <artifactId>OSGiExamWeb</artifactId>
        <version>1.0-SNAPSHOT</version>
        <packaging>war</packaging>
    
        <name>OSGiExamWeb</name>
    
        <properties>
            <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>${project.groupId}</groupId>
                <artifactId>OSGiExamApi</artifactId>
                <version>${project.version}</version>
            </dependency>
            <dependency>
                <groupId>org.glassfish</groupId>
                <artifactId>osgi-cdi-api</artifactId>
            </dependency>
            <dependency>
                <groupId>org.glassfish.main.extras</groupId>
                <artifactId>glassfish-embedded-all</artifactId>
            </dependency>
        </dependencies>
        ...
    
  3. WEB-INF/beans.xml を作成 (中身は空で良い)。CDIを使うために必要
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://java.sun.com/xml/ns/javaee"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
    </beans>
    

POJO OSGi バンドルを作る

  1. [新規]-[Maven]-[OSGiバンドル]
  2. /OSGiExam? 配下にモジュールとして OSGi Bundle アプリを作る (OSGiExam?/OSGiExamImpl? に作成)
  3. OSGiExam?/OSGiImpl?/pom.xml を編集して、親プロジェクト (OSGiExam?) の pom.xml のライブラリ参照定義を継承する。(GUI からやりたければ、ソースツリーの [依存性] を右クリックして、[依存性の追加]-[依存性管理] で、親プロジェクトの管理しているライブラリを追加できる)
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
        <artifactId>OSGiExam</artifactId>
        <groupId>com.mycompany</groupId>
        <version>1.0-SNAPSHOT</version>
      </parent>
    
        <groupId>com.mycompany</groupId>
        <artifactId>OSGiExamImpl</artifactId>
        <version>1.0-SNAPSHOT</version>
        <packaging>bundle</packaging>
    
        <name>OSGiExamImpl OSGi Bundle</name>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.osgi</groupId>
                <artifactId>org.osgi.core</artifactId>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>${project.groupId}</groupId>
                <artifactId>OSGiExamApi</artifactId>
                <version>${project.version}</version>
                <scope>provided</scope>
            </dependency>
        </dependencies>
        ...
    
  4. OSGiExamAPI にある Hello インタフェースの実装をする
    package com.mycompany.osgiexamimpl;
    
    import com.mycompany.osgiexamapi.Hello;
    
    public class HelloImpl implements Hello {
    
        @Override
        public String sayHello(String name) {
            return "Hello " + name;
        }    
    }
    
  5. Activator#start で、HelloImpl?BundleContext? に追加する
    package com.mycompany.osgiexamimpl;
    
    import com.mycompany.osgiexamapi.Hello;
    import org.osgi.framework.BundleActivator;
    import org.osgi.framework.BundleContext;
    
    public class Activator implements BundleActivator {
    
        @Override
        public void start(final BundleContext context) throws Exception {
            System.out.println(String.format("start::%s", Activator.class.getCanonicalName()));
            context.registerService(Hello.class.getName(), new HelloImpl(), null);
            System.out.println(String.format("activated::%s as %s", HelloImpl.class.getName(), Hello.class.getName()));
        }
    
        @Override
        public void stop(final BundleContext context) throws Exception {
            context.ungetService(context.getServiceReference(Hello.class.getName()));
            System.out.println(String.format("deactivated::%s", Hello.class.getName()));
            System.out.println(String.format("stop::%s", Activator.class.getCanonicalName()));
        }
    }
    
    バンドル初期化時には、まだ他のバンドルを参照できないことに注意。Logger も使えないよ (ハマった)、なにか出力したかったら System.out.prinltn() で

動かしてみる

  1. OSGiExamWeb? に、LookupPojoFromCDI を作って、HelloImpl? が CDI で injection できるか試してみる
    package com.mycompany.osgiexamweb;
    
    import com.mycompany.osgiexamapi.Hello;
    import java.io.IOException;
    import java.io.PrintWriter;
    import javax.annotation.Resource;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    @WebServlet(name = "LookupPojoFromCDI", urlPatterns = {"/LookupPojoFromCDI"})
    public class LookupPojoFromCDI extends HttpServlet {
    
        @Resource
        private Hello hello;
            
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            response.setContentType("text/html;charset=UTF-8");
            PrintWriter out = response.getWriter();
            try {
                out.println("<!DOCTYPE html>");
                out.println("<html>");
                out.println("<head>");
                out.println("<title>@Resource</title>");            
                out.println("</head>");
                out.println("<body>");
                out.println("<h1>lookup POJO by @Resource</h1>");
                out.println(hello.sayHello("Sachi"));
                out.println("<br/><br/><font color=\"gray\">Hello Class is ");
                out.println(hello.getClass().getCanonicalName());
                out.println("@");
                out.println(hello.hashCode());
                out.println("</font>");
            } catch (Exception ex) {
                out.println("<pre>");
                ex.printStackTrace(out);
                out.println("</pre>");
            } finally {
                out.println("</body>");
                out.println("</html>");
                out.close();
            }
        }
    }
    
  2. ビルド OSGiExam? で、[実行]-[消去してビルド]
    ...
    undle:install]
    Installing com/mycompany/OSGiExamImpl/1.0-SNAPSHOT/OSGiExamImpl-1.0-SNAPSHOT.jar
    Writing OBR metadata
    ------------------------------------------------------------------------
    Reactor Summary:
    
    OSGiExam .......................................... SUCCESS [21.206s]
    OSGiExamApi OSGi Bundle ........................... SUCCESS [6.011s]
    OSGiExamWeb ....................................... SUCCESS [4.712s]
    OSGiExamImpl OSGi Bundle .......................... SUCCESS [0.717s]
    ------------------------------------------------------------------------
    BUILD SUCCESS
    ------------------------------------------------------------------------
    Total time: 34.398s
    Finished at: Sat Sep 07 22:54:43 JST 2013
    Final Memory: 37M/90M
    ------------------------------------------------------------------------
  3. 配備
    [~]$ cp ~/NetBeansProjects/OSGiExam/OSGiExamApi/target/OSGiExamApi-1.0-SNAPSHOT.jar \
    /Applications/NetBeans/glassfish-3.1.2.2/glassfish/domains/domain1/autodeploy/bundles/
    
    [~]$ cp ~/NetBeansProjects/OSGiExam/OSGiExamImpl/target/OSGiExamImpl-1.0-SNAPSHOT.jar \
    /Applications/NetBeans/glassfish-3.1.2.2/glassfish/domains/domain1/autodeploy/bundles/
  4. OSGiExamWar? を実行
    impl1.png
    ちゃんと動いた。インスタンスは Activator で登録したもの (Singleton)

EJB OSGi バンドルを作る

  1. [新規]-[Maven]-[OSGiバンドル]
    ejb1.png
  2. 作成場所を OSGiExam? の直下にする
    ejb2.png
  3. pom.xml の編集
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <artifactId>OSGiExam</artifactId>
            <groupId>com.mycompany</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
    
        <groupId>com.mycompany</groupId>
        <artifactId>OSGiExamEjb</artifactId>
        <version>1.0-SNAPSHOT</version>
        <packaging>ejb</packaging>
    
        <name>OSGiExamEjb</name>
    
        <properties>
            <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>${project.groupId}</groupId>
                <artifactId>OSGiExamApi</artifactId>
                <version>${project.version}</version>
                <scope>provided</scope>
            </dependency>        
            <dependency>
                <groupId>org.glassfish.main.extras</groupId>
                <artifactId>glassfish-embedded-all</artifactId>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>2.3.2</version>
                    <configuration>
                        <source>1.6</source>
                        <target>1.6</target>
                        <compilerArguments>
                            <endorseddirs>${endorsed.dir}</endorseddirs>
                        </compilerArguments>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-ejb-plugin</artifactId>
                    <version>2.3</version>
                    <configuration>
                        <archive>
                            <!-- add bundle plugin generated manifest to the war -->
                            <manifestFile>
                                ${project.build.outputDirectory}/META-INF/MANIFEST.MF
                            </manifestFile>
                        </archive>
                        <ejbVersion>3.1</ejbVersion>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-dependency-plugin</artifactId>
                    <version>2.1</version>
                    <executions>
                        <execution>
                            <phase>validate</phase>
                            <goals>
                                <goal>copy</goal>
                            </goals>
                            <configuration>
                                <outputDirectory>${endorsed.dir}</outputDirectory>
                                <silent>true</silent>
                                <artifactItems>
                                    <artifactItem>
                                        <groupId>javax</groupId>
                                        <artifactId>javaee-endorsed-api</artifactId>
                                        <version>6.0</version>
                                        <type>jar</type>
                                    </artifactItem>
                                </artifactItems>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
                <plugin>
                    <groupId>org.apache.felix</groupId>
                    <artifactId>maven-bundle-plugin</artifactId>
                    <version>2.2.0</version>
                    <extensions>true</extensions>
                    <configuration>
                        <supportedProjectTypes>
                            <supportedProjectType>ejb</supportedProjectType>
                            <supportedProjectType>war</supportedProjectType>
                            <supportedProjectType>bundle</supportedProjectType>
                            <supportedProjectType>jar</supportedProjectType>
                        </supportedProjectTypes>
                        <instructions>
                            <!-- Specify elements to add to MANIFEST.MF -->
                            <Export-EJB>ALL</Export-EJB>
                            <!-- By default, nothing is exported -->
                            <Export-Package>!*.impl.*, *</Export-Package>
                        </instructions>
                    </configuration>
                    <executions>
                        <execution>
                            <id>bundle-manifest</id>
                            <phase>process-classes</phase>
                            <goals>
                                <goal>manifest</goal>
                            </goals>
                        </execution>
                        <execution>
                            <id>bundle-install</id>
                            <phase>install</phase>
                            <goals>
                                <goal>install</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin> 
            </plugins>
        </build>
    </project>
    
    • <dependencies> に、親プロジェクトへの参照を追加する
    • <maven-ejb-plugin> に、格納する MANIFEST.MF を maven-bundle-plugin が作ったものにするように指定する
    • <maven-bundle-plugin> を追加する。ミソは、Export-EJB : ALL (すべての SessionBean? を公開する)
  4. 自動生成される MANIFEST.MF はこんな感じ
    Manifest-Version: 1.0
    Archiver-Version: Plexus Archiver
    Created-By: 1.7.0_21 (Oracle Corporation)
    Built-By: atsushi
    Build-Jdk: 1.7.0_21
    Export-Package: com.mycompany.osgiexamejb;uses:="javax.ejb,com.mycompa
     ny.osgiexamapi"
    Export-EJB: ALL
    Bundle-Version: 1.0.0.SNAPSHOT
    Tool: Bnd-1.15.0
    Bundle-Name: OSGiExamEjb
    Bnd-LastModified: 1378646187379
    Bundle-ManifestVersion: 2
    Bundle-SymbolicName: com.mycompany.OSGiExamEjb
    Import-Package: com.mycompany.osgiexamapi;version="[1.0,2)",javax.ejb
  5. OSGiExamAPI にある Goodbye インタフェース (@Local) の実装をする
    package com.mycompany.osgiexamejb;
    
    import com.mycompany.osgiexamapi.GoodBye;
    import javax.ejb.Stateless;
    
    @Stateless
    public class GoodByeEjb implements GoodBye {
    
        @Override
        public String sayGoodBye(String name) {
            return "GoodBye " + name;
        }
    }
    

動かしてみる

  1. OSGiExamWeb? に、LookupEjbFromJNDI を作って、GoodByeEjb? が JNDI で injection できるか試してみる
    package com.mycompany.osgiexamweb;
    
    import com.mycompany.osgiexamapi.GoodBye;
    import java.io.IOException;
    import java.io.PrintWriter;
    import javax.ejb.EJB;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    @WebServlet(name = "LookupEjbFromJNDI", urlPatterns = {"/LookupEjbFromJNDI"})
    public class LookupEjbFromJNDI extends HttpServlet {
    
        @EJB(lookup = "java:global/com.mycompany.OSGiExamEjb_1.0.0.SNAPSHOT/GoodByeEjb")
        private GoodBye goodbye;
    
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            response.setContentType("text/html;charset=UTF-8");
            PrintWriter out = response.getWriter();
            try {
                out.println("<!DOCTYPE html>");
                out.println("<html>");
                out.println("<head>");
                out.println("<title>@EJB</title>");
                out.println("</head>");
                out.println("<body>");
                out.println("<h1>lookup EJB Object by @EJB</h1>");
                out.println(goodbye.sayGoodBye("Sachi"));
                out.println("<br/><br/><font color=\"gray\">GoodBye Class is ");
                out.println(goodbye.getClass().getCanonicalName());
                out.println("@");
                out.println(goodbye.hashCode());
                out.println("</font>");
            } catch (Exception ex) {
                out.println("<pre>");
                ex.printStackTrace(out);
                out.println("</pre>");
            } finally {
                out.println("</body>");
                out.println("</html>");
                out.close();
            }
        }
    }
    
  2. ビルドして
  3. 配備
    [~]$ cp ~/NetBeansProjects/OSGiExam/OSGiExamEjb/target/OSGiExamEjb-1.0-SNAPSHOT.jar \
    /Applications/NetBeans/glassfish-3.1.2.2/glassfish/domains/domain1/autodeploy/bundles/
  4. OSGiExamWar? を実行
    ejb3.png


Webアプリを Wab (Web Application Bundle) 化して、OSGi バンドルから OSGi バンドルを呼び出す

  1. pom.xml を変更して、MANIFEST.MF を自動生成する
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <artifactId>OSGiExam</artifactId>
            <groupId>com.mycompany</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
    
        <groupId>com.mycompany</groupId>
        <artifactId>OSGiExamWeb</artifactId>
        <version>1.0-SNAPSHOT</version>
        <packaging>war</packaging>
    
        <name>OSGiExamWeb</name>
    
        <properties>
            <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>${project.groupId}</groupId>
                <artifactId>OSGiExamApi</artifactId>
                <version>${project.version}</version>
            </dependency>
            <dependency>
                <groupId>org.glassfish</groupId>
                <artifactId>osgi-cdi-api</artifactId>
            </dependency>
            <dependency>
                <groupId>org.glassfish.main.extras</groupId>
                <artifactId>glassfish-embedded-all</artifactId>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>2.3.2</version>
                    <configuration>
                        <source>1.6</source>
                        <target>1.6</target>
                        <compilerArguments>
                            <endorseddirs>${endorsed.dir}</endorseddirs>
                        </compilerArguments>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-war-plugin</artifactId>
                    <version>2.1.1</version>
                    <configuration>
                        <archive>
                            <!-- add bundle plugin generated manifest to the war -->
                            <manifestFile>
                                ${project.build.outputDirectory}/META-INF/MANIFEST.MF
                            </manifestFile>
                            <!-- For some reason, adding Bundle-ClassPath in maven-bundle-plugin
                            confuses that plugin and it generates wrong Import-Package, etc.
                            So, we generate it here.-->
                            <manifestEntries>
                                <Bundle-ClassPath>WEB-INF/classes/</Bundle-ClassPath>
                            </manifestEntries>
                        </archive>
                        <failOnMissingWebXml>false</failOnMissingWebXml>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-dependency-plugin</artifactId>
                    <version>2.1</version>
                    <executions>
                        <execution>
                            <phase>validate</phase>
                            <goals>
                                <goal>copy</goal>
                            </goals>
                            <configuration>
                                <outputDirectory>${endorsed.dir}</outputDirectory>
                                <silent>true</silent>
                                <artifactItems>
                                    <artifactItem>
                                        <groupId>javax</groupId>
                                        <artifactId>javaee-endorsed-api</artifactId>
                                        <version>6.0</version>
                                        <type>jar</type>
                                    </artifactItem>
                                </artifactItems>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
                <plugin>
                    <groupId>org.apache.felix</groupId>
                    <artifactId>maven-bundle-plugin</artifactId>
                    <version>2.2.0</version>
                    <extensions>true</extensions>
                    <configuration>
                        <supportedProjectTypes>
                            <supportedProjectType>ejb</supportedProjectType>
                            <supportedProjectType>war</supportedProjectType>
                            <supportedProjectType>bundle</supportedProjectType>
                            <supportedProjectType>jar</supportedProjectType>
                        </supportedProjectTypes>
                        <instructions>
                            <!-- Specify elements to add to MANIFEST.MF -->
                            <Web-ContextPath>/mavenhellowebclient</Web-ContextPath>
                            <!-- By default, nothing is exported -->
                            <Export-Package>!*.impl.*, *</Export-Package>
                        </instructions>
                    </configuration>
                    <executions>
                        <execution>
                            <id>bundle-manifest</id>
                            <phase>process-classes</phase>
                            <goals>
                                <goal>manifest</goal>
                            </goals>
                        </execution>
                        <execution>
                            <id>bundle-install</id>
                            <phase>install</phase>
                            <goals>
                                <goal>install</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>            
            </plugins>
        </build>
    </project>
    
    • maven-war-plugin で、maven-bundle-plugin が作成した MANIFEST.MF を取り込むように設定する
    • maven-bundle-plugin を追加する
  2. 自動生成される MANIFEST.MF はこんな感じ
    Manifest-Version: 1.0
    Archiver-Version: Plexus Archiver
    Created-By: 1.7.0_21 (Oracle Corporation)
    Built-By: atsushi
    Build-Jdk: 1.7.0_21
    Bundle-ClassPath: WEB-INF/classes/
    Export-Package: com.mycompany.osgiexamweb;uses:="javax.servlet,javax.e
     jb,com.mycompany.osgiexamapi,javax.servlet.annotation,javax.servlet.h
     ttp,org.glassfish.osgicdi,javax.inject,javax.annotation"
    Bundle-Version: 1.0.0.SNAPSHOT
    Tool: Bnd-1.15.0
    Bundle-Name: OSGiExamWeb
    Bnd-LastModified: 1378649661814
    Bundle-ManifestVersion: 2
    Bundle-SymbolicName: com.mycompany.OSGiExamWeb
    Web-ContextPath: /mavenhellowebclient
    Import-Package: com.mycompany.osgiexamapi;version="[1.0,2)",javax.anno
     tation,javax.ejb,javax.inject,javax.servlet,javax.servlet.annotation,
     javax.servlet.http,org.glassfish.osgicdi;version="[1.0,2)"

動かしてみる

  1. OSGiExamWeb? に、LookupPojoFromOSGi を作って、HelloImpl? が OSGi で injection できるか試してみる
    package com.mycompany.osgiexamweb;
    
    import com.mycompany.osgiexamapi.Hello;
    import java.io.IOException;
    import java.io.PrintWriter;
    import javax.inject.Inject;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import org.glassfish.osgicdi.OSGiService;
    
    @WebServlet(name = "LookupPojoFromOSGi", urlPatterns = {"/LookupPojoFromOSGi"})
    public class LookupPojoFromOSGi extends HttpServlet {
    
        @Inject
        @OSGiService(dynamic = true)
        private Hello hello;
            
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            response.setContentType("text/html;charset=UTF-8");
            PrintWriter out = response.getWriter();
            try {
                out.println("<!DOCTYPE html>");
                out.println("<html>");
                out.println("<head>");
                out.println("<title>@OSGi</title>");            
                out.println("</head>");
                out.println("<body>");
                out.println("<h1>lookup POJO by @Inject @OSGiService</h1>");
                out.println(hello.sayHello("Sachi"));
                out.println("<br/><br/><font color=\"gray\">Hello Class is ");
                out.println(hello.getClass().getCanonicalName());
                out.println("@");
                out.println(hello.hashCode());
                out.println("</font>");
            } catch (Exception ex) {
                out.println("<pre>");
                ex.printStackTrace(out);
                out.println("</pre>");
            } finally {
                out.println("</body>");
                out.println("</html>");
                out.close();
            }
        }
    }
    
  2. OSGiExamWeb? に、LookupEjbFromOSGi を作って、GoodByeEjb? が OSGi で injection できるか試してみる
    package com.mycompany.osgiexamweb;
    
    import com.mycompany.osgiexamapi.GoodBye;
    import java.io.IOException;
    import java.io.PrintWriter;
    import javax.inject.Inject;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import org.glassfish.osgicdi.OSGiService;
    
    @WebServlet(name = "LookupEjbFromOSGi", urlPatterns = {"/LookupEjbFromOSGi"})
    public class LookupEjbFromOSGi extends HttpServlet {
    
        @Inject
        @OSGiService(dynamic = true)
        private GoodBye goodbye;
            
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            response.setContentType("text/html;charset=UTF-8");
            PrintWriter out = response.getWriter();
            try {
                out.println("<!DOCTYPE html>");
                out.println("<html>");
                out.println("<head>");
                out.println("<title>@OSGi</title>");            
                out.println("</head>");
                out.println("<body>");
                out.println("<h1>lookup EJB Object by @Inject @OSGiService</h1>");
                out.println(goodbye.sayGoodBye("Sachi"));
                out.println("<br/><br/><font color=\"gray\">GoodBye Class is ");
                out.println(goodbye.getClass().getCanonicalName());
                out.println("@");
                out.println(goodbye.hashCode());
                out.println("</font>");
            } catch (Exception ex) {
                out.println("<pre>");
                ex.printStackTrace(out);
                out.println("</pre>");
            } finally {
                out.println("</body>");
                out.println("</html>");
                out.close();
            }
        }
    }
    
  3. 配備する
    [~]$ cp ~/NetBeansProjects/OSGiExam/OSGiExamWeb/target/OSGiExamWeb-1.0-SNAPSHOT.war \
    /Applications/NetBeans/glassfish-3.1.2.2/glassfish/domains/domain1/autodeploy/bundles/
  4. 実行する (URL は MANIFEST.MF の 「Web-ContextPath?: /mavenhellowebclient」 )
    osgi1.png
    osgi2.png

OSGi バンドルに jar を入れたい

OSGi バンドルの管理


Java#Glassfish }}


添付ファイル: fileosgi2.png 2309件 [詳細] fileosgi1.png 2302件 [詳細] fileejb3.png 2476件 [詳細] fileejb2.png 2632件 [詳細] fileejb1.png 2492件 [詳細] fileimpl1.png 2382件 [詳細] fileweb1.png 2360件 [詳細] fileapi4.png 2307件 [詳細] fileapi3.png 2309件 [詳細] fileapi2.png 2358件 [詳細] fileapi1.png 2434件 [詳細] fileparent2.png 1930件 [詳細] fileparent1.png 2152件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS   sitemap
Last-modified: 2013-11-20 (水) 01:06:38 (4033d)
Short-URL:
ISBN10
ISBN13
9784061426061