簡體   English   中英

在 Apache Felix 上部署 OSGi

[英]OSGi deployment on Apache Felix

我已經創建了我的第一個 OSGi 服務,並試圖將它部署在 Apache Felix 上。 后來查看系統控制台,發現服務沒有激活,出現了一些問題:

org.springframework.ws.client.core,version=[2.1,3) -- Cannot be resolved
org.springframework.ws.soap,version=[2.1,3) -- Cannot be resolved
org.springframework.ws.soap.axiom,version=[2.1,3) -- Cannot be resolved
org.springframework.ws.soap.saaj,version=[2.1,3) -- Cannot be resolved

所以我查看了哪個 jar 包含這些包,這來自 spring-ws-core-2.1.2.RELEASE.jar,它也是一個 OSGi 包。 我也部署了那個,但又出現了以下錯誤消息:

org.springframework.web.servlet,version=[3.1.0, 4.0.0) -- Cannot be resolved

再次依賴,這次是在 spring-webmvc-3.2.17.RELEASE.jar 上。 然而,問題是這不是 OSGi 包,那么我該如何解決這個問題呢? 由於它是第三方庫,因此我能想到的不多。

那么如何在 OSGi 容器中使用非捆綁 jars 呢? 以及如何自動解決依賴樹而不必手動解決所有問題?

我創建了osgi-run項目來解決這個問題,即使用標准的 Maven 依賴項解析(而不是沒有廣泛支持的 OBR,不幸的是)解決這個問題,由 Gradle 支持。

然而,Spring jar 是一個可怕的噩夢,因為幾年前 Spring 項目放棄了對 OSGi 的支持。

理論上,使用 osgi-run,您應該能夠使用以下 gradle 文件創建包含 spring-ws-core 包的 OSGi 環境:

plugins {
    id "com.athaydes.osgi-run" version "1.5.1"
}

repositories {
    mavenLocal()
    jcenter()
}

dependencies {
    osgiRuntime 'org.springframework.ws:spring-ws-core:2.1.1.RELEASE'
}

這依賴於 poms 中的信息是一致的。 如果發現任何非捆綁包,它會自動轉換為 OSGi 捆綁包(參見wrapping jars )。

但是,這不起作用...... Gradle 可以打印 spring-ws-core jar 的依賴層次結構,這是我使用它時得到的:

+--- org.springframework.ws:spring-ws-core:2.1.1.RELEASE
|    +--- org.springframework.ws:spring-xml:2.1.1.RELEASE
|    |    +--- org.springframework:spring-context:3.1.2.RELEASE
|    |    |    +--- org.springframework:spring-aop:3.1.2.RELEASE
|    |    |    |    +--- aopalliance:aopalliance:1.0
|    |    |    |    +--- org.springframework:spring-asm:3.1.2.RELEASE
|    |    |    |    +--- org.springframework:spring-beans:3.1.2.RELEASE
|    |    |    |    |    \--- org.springframework:spring-core:3.1.2.RELEASE
|    |    |    |    |         +--- org.springframework:spring-asm:3.1.2.RELEASE
|    |    |    |    |         \--- commons-logging:commons-logging:1.1.1
|    |    |    |    \--- org.springframework:spring-core:3.1.2.RELEASE (*)
|    |    |    +--- org.springframework:spring-beans:3.1.2.RELEASE (*)
|    |    |    +--- org.springframework:spring-core:3.1.2.RELEASE (*)
|    |    |    +--- org.springframework:spring-expression:3.1.2.RELEASE
|    |    |    |    \--- org.springframework:spring-core:3.1.2.RELEASE (*)
|    |    |    \--- org.springframework:spring-asm:3.1.2.RELEASE
|    |    +--- commons-logging:commons-logging:1.1.1
|    |    +--- org.springframework:spring-core:3.1.2.RELEASE (*)
|    |    \--- org.springframework:spring-beans:3.1.2.RELEASE (*)
|    +--- org.springframework:spring-context:3.1.2.RELEASE (*)
|    +--- org.springframework:spring-aop:3.1.2.RELEASE (*)
|    +--- org.springframework:spring-oxm:3.1.2.RELEASE
|    |    +--- commons-lang:commons-lang:2.5
|    |    +--- org.springframework:spring-beans:3.1.2.RELEASE (*)
|    |    +--- org.springframework:spring-context:3.1.2.RELEASE (*)
|    |    \--- org.springframework:spring-core:3.1.2.RELEASE (*)
|    +--- org.springframework:spring-web:3.1.2.RELEASE
|    |    +--- aopalliance:aopalliance:1.0
|    |    +--- org.springframework:spring-beans:3.1.2.RELEASE (*)
|    |    +--- org.springframework:spring-context:3.1.2.RELEASE (*)
|    |    \--- org.springframework:spring-core:3.1.2.RELEASE (*)
|    +--- org.springframework:spring-webmvc:3.1.2.RELEASE
|    |    +--- org.springframework:spring-asm:3.1.2.RELEASE
|    |    +--- org.springframework:spring-beans:3.1.2.RELEASE (*)
|    |    +--- org.springframework:spring-context:3.1.2.RELEASE (*)
|    |    +--- org.springframework:spring-context-support:3.1.2.RELEASE
|    |    |    +--- org.springframework:spring-beans:3.1.2.RELEASE (*)
|    |    |    +--- org.springframework:spring-context:3.1.2.RELEASE (*)
|    |    |    \--- org.springframework:spring-core:3.1.2.RELEASE (*)
|    |    +--- org.springframework:spring-core:3.1.2.RELEASE (*)
|    |    +--- org.springframework:spring-expression:3.1.2.RELEASE (*)
|    |    \--- org.springframework:spring-web:3.1.2.RELEASE (*)
|    +--- wsdl4j:wsdl4j:1.6.1
|    +--- commons-logging:commons-logging:1.1.1
|    +--- org.springframework:spring-core:3.1.2.RELEASE (*)
|    \--- org.springframework:spring-beans:3.1.2.RELEASE (*)

我認為依賴解析中可能存在一些錯誤,因為根據上面解析的依賴關系圖,似乎 Spring 2 jar 與 Spring 3 jar 混合在一起! 但是不…… 完全正確

但無論如何,經過一番調查,我得到了這個工作......

調查未滿足的捆綁需求

首先,我注意到 Spring AOP 沒有解決,因為它的org.aopalliance.aop要求。

顯然,這應該來自 aopalliance jar(它不是一個包,至少不是 Maven Central/JCenter 中的那個)。

我在 Gradle 文件的runOsgi塊中添加了這條指令,以便我可以看到osgi-run如何將 jar 打包成一個包:

wrapInstructions {
    printManifests = true
}

再次運行gradle clean createOsgi ,清單被打印出來......它看起來像這樣:

--------------------------------- Manifest for aopalliance-1.0.jar ---------------------------------
Manifest-Version: 1.0
Bundle-SymbolicName: aopalliance
Bundle-ManifestVersion: 2
Bnd-LastModified: 1474120107912
Import-Package: org.aopalliance.aop
Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.3))"
Tool: Bnd-3.1.0.201512181341
Ant-Version: Apache Ant 1.5.4 
Originally-Created-By: 1.4.2_01-b06 (Sun Microsystems Inc.)
Export-Package: org.aopalliance.aop,org.aopalliance.intercept;uses:="o
 rg.aopalliance.aop"
Bundle-Version: 1.0.0
Bundle-Name: aopalliance
Created-By: 1.8.0_60 (Oracle Corporation)

----------------------------------------------------------------------------------------------------

請注意,有一個正確生成的Bundle-Version ,但包沒有與該版本一起導出......通過添加以下指令,我們可以強制使用版本導出包:

wrapInstructions {
    printManifests = true
    manifest( 'aopalliance.*' ) {
        instruction 'Export-Package', '*;version=1.0'
    }
}

現在,清單中的Export-Package指令是正確的:

Export-Package: org.aopalliance.aop;version="1.0",org.aopalliance.inte
rcept;version="1.0";uses:="org.aopalliance.aop"

然后運行 ​​OSGi 容器,我們看到 Spring AOP bundle 仍然沒有解決,但是現在唯一的問題是因為它的(&(osgi.wiring.package=org.apache.commons.logging)(version>=1.1.1)(!(version>=2.0.0)))要求不滿足。

commons.logging jar 有一個已知問題( 記錄osgi-run README 頁面中)...它聲明了可選的依賴項,使其難以自動包裝。

但此外, commons.logging jar 在清單中的Specification-Version不正確。 它說1.0而不是1.1.1 ,這就是osgi-run用於捆綁版本的內容,因此Bundle-Version獲得了不正確的值。

通過還強制osgi-run導出具有正確版本的包,包裝工作正常並且 Spring AOP 正確啟動:

manifest( /commons-logging.*/ ) {
    instruction 'Import-Package', '!javax.servlet,!org.apache.*,*'
    instruction 'Export-Package', '*;version=1.1.1'
}

現在,繼續下一個問題,我們注意到org.springframework.web沒有解決,因為它要求(&(osgi.wiring.package=javax.servlet)(version>=2.4.0)(!(version>=4.0.0)))

這個很簡單,將 servlet-api 包(由 Felix 提供)添加到 OSGi 運行時,它應該可以工作......只需在 Gradle 文件中添加這個依賴項:

osgiRuntime 'org.apache.felix:org.apache.felix.http.servlet-api:1.1.2'

現在,OSGi 環境啟動沒有任何故障!

最終解決方案

這是安裝的全套捆綁包:

   ID|State      |Level|Name
    0|Active     |    0|System Bundle (5.4.0)|5.4.0
    1|Active     |    1|aopalliance (1.0.0)|1.0.0
    2|Active     |    1|Commons Lang (2.5.0)|2.5.0
    3|Active     |    1|Jakarta Commons Logging (1.0.0)|1.0.0
    4|Active     |    1|Apache Felix Gogo Command (0.16.0)|0.16.0
    5|Active     |    1|Apache Felix Gogo Runtime (0.16.2)|0.16.2
    6|Active     |    1|Apache Felix Gogo Shell (0.12.0)|0.12.0
    7|Active     |    1|Apache Felix Servlet API (1.1.2)|1.1.2
    8|Active     |    1|Spring AOP (3.1.2.RELEASE)|3.1.2.RELEASE
    9|Active     |    1|Spring ASM (3.1.2.RELEASE)|3.1.2.RELEASE
   10|Active     |    1|Spring Beans (3.1.2.RELEASE)|3.1.2.RELEASE
   11|Active     |    1|Spring Context (3.1.2.RELEASE)|3.1.2.RELEASE
   12|Active     |    1|Spring Context Support (3.1.2.RELEASE)|3.1.2.RELEASE
   13|Active     |    1|Spring Core (3.1.2.RELEASE)|3.1.2.RELEASE
   14|Active     |    1|Spring Expression Language (3.1.2.RELEASE)|3.1.2.RELEASE
   15|Active     |    1|Spring Object/XML Mapping (3.1.2.RELEASE)|3.1.2.RELEASE
   16|Active     |    1|Spring Web (3.1.2.RELEASE)|3.1.2.RELEASE
   17|Active     |    1|Spring Web Servlet (3.1.2.RELEASE)|3.1.2.RELEASE
   18|Active     |    1|Spring Web Services Core (2.1.1.RELEASE)|2.1.1.RELEASE
   19|Active     |    1|Spring XML (2.1.1.RELEASE)|2.1.1.RELEASE
   20|Active     |    1|tomcat-servlet-api (8.0.0)|8.0.0
   21|Active     |    1|JWSDL (1.2.0)|1.2.0

如果您想嘗試osgi-run ,這是我使用的 Gradle 文件:

plugins {
    id "com.athaydes.osgi-run" version "1.5.1"
}

repositories {
    mavenLocal()
    jcenter()
}

dependencies {
    osgiRuntime 'org.springframework.ws:spring-ws-core:2.1.1.RELEASE'
    osgiRuntime 'org.apache.felix:org.apache.felix.http.servlet-api:1.1.2'
}

runOsgi {
    wrapInstructions {
        printManifests = true
        manifest( 'aopalliance.*' ) {
            instruction 'Export-Package', '*;version=1.0'
        }
        manifest( /commons-logging.*/ ) {
            instruction 'Import-Package', '!javax.servlet,!org.apache.*,*'
            instruction 'Export-Package', '*;version=1.1.1'
        }
    }
}

只需將其保存在build.gradle文件中,然后運行gradle createOsgi以在build/osgi/run.sh獲取您的啟動腳本。

我將在osgi-run上工作以嘗試使這些問題自動解決,希望在下一個版本中,上面顯示的第一個構建文件將毫不費力地工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM