2012-01-24 28 views
4

我熟悉Spring OSGI和Blueprint,但是遇到了「classpath」困難(像許多新手一樣)。必須通過使用bundle來顯式導入Spring OSGI服務引用接口?

我有兩個OSGI包 - 一個定義各種bean(使用藍圖,不是它應該重要),並將它們導出爲服務;和另一個引用服務bean的bundle(使用Spring OSGI)並將它們插入一些Apache Camel路由。

服務提供商捆綁的藍圖看起來是這樣的:

<service id="camelTsvDataFormat" 
    interface="org.apache.camel.spi.DataFormat"> 
    <bean class="org.apache.camel.component.flatpack.FlatpackDataFormat"/> 
</service> 

服務消費者包的Spring上下文看起來是這樣的:

<osgi:reference id="tsvDataFormat" 
    interface="org.apache.camel.spi.DataFormat" /> 

<camel:camelContext> 
    <route> 
     <from uri="vm:in"> 
     <setBody> 
      <constant>SELECT * FROM myTable</constant> 
     </setBody> 
     <to uri="jdbc:myDataSource" /> 
     <marshal ref="tsvDataFormat" /> 
     <to uri="file:/path/to/my/files/?fileName=out.tsv" /> 
    </route> 
</camel:camelContext> 

...但是在部署時,春「無法找到類[org.apache.camel.spi.DataFormat]「。我可以將接口添加到我的Bnd指令的Import-Package部分,但似乎是多餘的,必須在不同位置手動列出兩次類。

另一種選擇是在我自己的項目中擴展接口,因此Bnd會自動將其接入,但這大致同樣麻煩。

我想我期望Spring通過接口名稱來查找服務,而不必實際解析接口類。這是不是na ï ve?或者有沒有辦法讓Bnd在我的appContext的服務引用中自動導入接口?如果Bnd可以執行此操作(例如使用插件),那麼是否有一種標準方式將Maven的Apache Felix捆綁插件使用Bnd插件?

+0

這是最接近的討論中,我可以找到: http://forum.springsource.org/archive/index.php/t-52913.html – RubyTuesdayDONO

+0

另一個想法 - 這是不是這樣一個大問題,如果與Apache Camel一樣,服務提供者接口能夠很好地集成到「spi」包中? – RubyTuesdayDONO

+0

通常bnd會爲字節碼中引用的任何包添加導入。什麼類的tsvDataFormat字段? –

回答

3

正如Holly所建議的那樣,bnd通常會從您的包中調用它的任何字節碼中找到引用該包的東西。它還應該反思Spring-DM XML文件,如果它們位於正確的位置。但是我不知道它是否以相同的方式支持Blueprint XML文件,因爲它們不在相同的位置。因此,可能需要升級bnd的版本或使用支持Blueprint的插件。

但是,我懷疑這件事。如果沒有字節碼引用到接口,那麼你甚至沒有使用服務引用?那麼,爲什麼不把它刪除呢?

+0

'tsvDataFormat'從另一個使用Blueprint的獨立包導出爲OSGI服務,所以字節碼不直接引用這個包的任何項目類,它使用Spring-OSGI導入引用。我很抱歉沒有澄清這一點。然而,除了Spring需要將這個bean插入到我的Apache Camel路由之外,我對這個接口沒有直接的興趣。 OSGI是否不自動/動態地導入引用服務的接口類? – RubyTuesdayDONO

+0

@RubyTuesdayDONO我不是在談論服務的實現的字節碼,正如你所說的是在另一個包中,不應該被導入。我在談論* interface *,它將被你的包中的任何類引用。如果你沒有在任何地方引用這個服務,那麼這意味着你沒有任何實際上調用這個服務的代碼,所以我仍然不清楚爲什麼你甚至需要這個引用。 –

+0

@RubyTuesdayDONO關於你的其他問題:不,OSGi從不自動導入任何東西(好吧,有一個例外:JRE中的'java。*'包總是可見的)。您必須導入想要具有可見性的每個軟件包,包括服務界面。通常情況下,導入將由bnd自動添加,因爲它會從您的代碼中看到對該接口的引用。 –

1

正如@Neil Bartlett所指出的那樣,Bnd應該在包(META-INF/springOSGI-INF/blueprint)中的標準位置上反思Spring和Blueprint文件。我在我的POM中手動覆蓋了這些爲META-INF/spring/*.xmlOSGI-INF/blueprint/*.xml。我認爲這很好,因爲我的OSGI平臺中的Spring和Blueprint擴展器接受了頭文件並引導了相應的容器。不過,Bnd似乎期望沒有球體的球頭更簡單(見SpringXMLType.java)。我不是故意的,因爲它是一個了不起的工具,但是這個引起了我的警惕。無論如何,既然我的Spring和Blueprint標記已經在標準位置,我只是從我的POM中刪除了多餘的Bnd指令,並且所有的Spring-DM服務參考接口都被自動獲取,Import-Package'

<plugin> 
    <groupId>org.apache.felix</groupId> 
    <artifactId>maven-bundle-plugin</artifactId> 
    <version>2.3.6</version> 
    <extensions>true</extensions> 
    <configuration> 
     <instructions> 
      <Bundle-Version>${project.version}.${buildNumber}</Bundle-Version> 
      <Bundle-Activator>com.example.BundleActivator</Bundle-Activator> 
      <!-- 
       <Spring-Context>META-INF/spring/*.xml</Spring-Context> 
       <Bundle-Blueprint>OSGI-INF/blueprint*.xml</Bundle-Blueprint> 
      --> 
     </instructions> 
    </configuration> 
</plugin>