日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

使普通的旧Java OSGi兼容

發布時間:2023/12/3 java 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使普通的旧Java OSGi兼容 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

盡管OSGi在Java世界中越來越流行,但仍有許多Java應用程序和庫尚未設計成可在OSGi中使用。 有時您可能需要在OSGi環境中運行這樣的代碼,或者是因為您想利用OSGi本身提供的好處,或者因為您需要僅由該特定環境提供的某些功能。 通常,您負擔不起完全遷移到OSGi的負擔,或者至少需要一個過渡期,在此期間,您的代碼在OSGi內外均可以正常工作。 當然,您希望以最小的努力做到這一點,而又不會增加軟件的復雜性。

最近,我們在SAP的團隊面臨著類似的挑戰。 我們有一個相當大的遺留普通Java應用程序,多年來,它已發展為包括許多本地框架和自定義解決方案。 我們需要為此應用程序提供基于REST的接口,因此我們要么必須包含Web服務器,要么必須在具有該Web服務器的環境中運行。 我們選擇使用SAP Lean Java Server(LJS) ,后者是SAP NetWeaver Cloud背后的引擎,其中包括Tomcat和其他有用的服務。 但是,LJS基于Eclipse的OSGi實現Equinox ,因此我們需要確保我們的代碼與OSGi兼容,以確保流暢的互操作性。 在此過程中,我們學到了很多有關該主題的知識,因此我想在本文中與您分享我們最有趣的發現。

為了使純Java代碼在OSGi環境中順利運行,應滿足以下先決條件:

  • 它打包為OSGi捆綁包 ,即具有有效OSGi清單的jar存檔。
  • 它遵守OSGi對動態加載類施加的要求和限制。
  • 它的所有軟件包僅由一個捆綁軟件導出,即沒有不同的捆綁軟件導出同一軟件包。

同樣,在許多情況下,您可能需要為要從OSGi控制臺啟動的應用程序創建新的入口點。 如果使用Equinox,則應考慮為此目的創建一個Equinox應用程序。

請注意,滿足以上要求既不意味著您不應該以任何方式將代碼遷移到OSGi,使其僅在OSGi中運行,也不意味著您應從根本上將開發環境或過程更改為基于OSGi。 相反,我們的經驗表明,通過以下列方式滿足上述要求,很可能實現與OSGi的兼容性 ,而不會失去在OSGi外部運行的能力,并且不會顯著改變您的開發方法和工具:

  • 可以使用BND和其他基于它的工具自動生成所有OSGi清單。 在OSGi之外,不使用這些清單,但也不會造成傷害。
  • 基于Class.forName()動態加載類和自定義類加載可以由使用引擎蓋下本機OSGi服務的幾乎相同的機制代替。 可以根據您的代碼是否在OSGi中執行而在原始和OSGi機制之間動態切換,而對現有代碼的更改很少。
  • 另外,通過使用OSGi服務機制動態注冊和發現“命名”實現,您可以完全擺脫OSGi中的動態類加載。
  • 由多個捆綁軟件導出的相同軟件包應該簡單地重命名。 顯然,這也適用于OSGi。
  • 通過將所有特定于OSGi的代碼放在有限數量的包中,可以最大程度地減少對OSGi的依賴性,這些包最好也不包含應在OSGi外部執行的代碼。

以下各節提供有關如何實現的更多詳細信息。

包裝為OSGi捆綁包

為了在OSGi環境中工作,所有Java代碼都應打包為OSGi捆綁包。 這不僅適用于由構建生成的所有存檔,還適用于作為軟件的一部分提供的所有依賴項。

如果您的構建使用Maven,則應強烈考慮使用Maven Bundle插件 (內部使用BND)為該構建生成的所有檔案生成有效的OSGi清單。 在大多數情況下,由該插件的默認配置生成的清單將可以正常工作。 但是,在某些情況下,可能需要進行一些細微的調整和添加才能生成正確的清單,例如:

  • 為僅通過反射使用的類添加其他導入包,因此BND無法找到。
  • 為公開OSGi聲明性服務的分發包指定服務組件XML。
  • 為依賴于自定義激活的捆綁軟件指定捆綁軟件激活器。

在我們的項目中,如下所述,在我們的父POM中配置了bundle插件:

<properties><classpath></classpath><import-package>*</import-package><export-package>{local-packages}</export-package><bundle-directives></bundle-directives><bundle-activator></bundle-activator><bundle-activationpolicy></bundle-activationpolicy><require-bundle></require-bundle><service-component></service-component>... </properties> ... <build><pluginManagement><plugins><plugin><groupId>org.apache.felix</groupId><artifactId>maven-bundle-plugin</artifactId><version>2.3.4</version><extensions>true</extensions><configuration><encoding>${project.build.sourceEncoding}</encoding><archive> <forced>true</forced> </archive><instructions><Bundle-SymbolicName>${project.artifactId}${bundle-directives}</Bundle-SymbolicName><Bundle-Name>${project.artifactId}</Bundle-Name><_nouses>true</_nouses><Class-Path>${classpath}</Class-Path><Export-Package>${export-package}</Export-Package><Import-Package>${import-package}</Import-Package><Bundle-Activator>${bundle-activator}</Bundle-Activator><Bundle-ActivationPolicy>${bundle-activationpolicy}</Bundle-ActivationPolicy><Require-Bundle>${require-bundle}</Require-Bundle><Service-Component>${service-component}</Service-Component></instructions></configuration><executions><execution><id>bundle-manifest</id><phase>process-classes</phase><goals><goal>manifest</goal></goals></execution></executions></plugin>...</plugins></pluginManagement> </build>

在子POM中,我們指定任何需要具有與默認值不同的值的屬性。 在我們的案例中,這種POM相對較少。

我們的大多數依賴項也沒有OSGi清單,因此我們在構建過程中生成它們。 當前,這是通過使用BND wrap命令的Groovy腳本完成的。 對于我們的大多數依賴項,對清單使用通用模板就足夠了。 當前,我們使用以下模板,該模板由腳本動態生成:

Bundle-Name: ${artifactId} Bundle-SymbolicName: ${artifactId} Bundle-Version: ${version} -nouses: true Export-Package: com.sap.*;version=${version_space},* Import-Package: com.sap.*;version="[${version_space},${version_space}]";resolution:=optional,*;resolution:=optional

一世
僅在少數情況下,清單模板必須包含特定于混凝土罐的信息。 我們通過在SCM中提交這些模板并使用提交的版本而不是默認版本來捕獲這些細節。

符合OSGi類加載

常用的類加載機制的替代方法

OSGi環境強加了自己的類加載機制,以下文章中對此進行了詳細描述:

  • OSGi類加載
  • OSGi中的類加載和類型可見性

但是,一些普通的Java應用程序和庫通常廣泛依賴于創建自定義類加載器并通過Class.forName()或ClassLoader.loadClass()加載類,以使用反射 ,我們的應用程序就是其中之一。 這在OSGi中是有問題的,如《 OSGi準備就緒-加載類》中更詳細描述。 本文提出的解決方案雖然有效,但不能直接應用于我們的案例,因為這將涉及大量更改舊代碼,這是我們目前不希望做的事情。

我們發現,可以完全依靠本機OSGi機制以優雅的方式解決此問題,對于我們的大部分遺留代碼而言都是透明的。 代替Class.forName() ,可以使用以下調用順序:

  • 使用FrameworkUtil.getBundle()獲取當前的Bundle及其BundleContext 。
  • 通過上一步中獲得的捆綁包上下文從OSGi服務注冊表中獲取標準PackageAdmin服務
  • 使用PackageAdmin.getExportedPackage()和ExportedPackage.getExportingBundle()查找ExportedPackage.getExportingBundle() Bundle包。
  • 最后,只需調用Bundle.loadClass()即可加載請求的類。

另外,盡管不可能直接使用低級別的捆綁包類加載器,但捆綁包類本身提供了諸如Bundle.loadClass()和Bundle.getResource()類的類加載方法。 因此,可以創建一個自定義的類加載器,該類加載器包裝一個包(或多個包)并委托給這些方法。

要使您的大部分遺留代碼在OSGi中工作,而只需進行少量更改,就可以通過以下方式對其進行調整:

  • 如果代碼在OSGi中執行,則代替調用Class.forName() ,而調用實現上述序列的方法。
  • 如果代碼在OSGi中執行, BundleClassLoader要從多個jar文件中創建自定義類加載器,而BundleClassLoader與這些jar文件相對應的BundleClassLoader包中創建BundleClassLoader 。

為了使上述更改更加直接,我們在應用程序中引入了一個名為ClassHelper的新類。 它是一個單例,提供以下靜態助手方法,這些方法委托給單個實例的相同非靜態方法:

public static boolean isOsgi(); public static Object getBundleContext(Class&lt;?&gt; clazz); public static Class&lt;?&gt; forName(String className, ClassLoader cl) throws ClassNotFoundException; public static ClassLoader getBundleClassLoader(String[] bundleNames, ClassLoader cl);

這些方法的默認實現在基本ClassHelper類中實現了默認的非OSGi行為– isOsgi()返回false, getBundleContext()和getBundleClassLoader()返回null, forName()只是委托給Class.forName() 。

OsgiClassHelper類繼承自ClassHelper并依次實現上述正確的OSGi行為。 我們將該類放在其自己的特殊捆綁包中,以確保包含ClassHelper和大量其他實用程序的捆綁包不受OSGi依賴關系的影響。 這個特殊的捆綁有一個Activator ,它取代了默認ClassHelper用一個實例OsgiClassHelper在束激活實例。 由于激活代碼僅在OSGi中執行,因此可以確保在兩種情況下均加載正確的實現。

在我們其余的代碼中, ClassHelper.forName()替換Class.forName()調用,并使用ClassHelper.forName()創建自定義類加載器就ClassHelper.getBundleClassLoader() 。

使用OSGi服務

在許多普通的Java應用程序中,某些實現是基于字符串“ handle”(類名本身或其他名稱)加載的。 通常將ClassLoader.loadClass()與自定義類加載結合使用,通常用于此目的。 OSGi提供了OSGi服務機制,用于注冊和發現此類“命名”的實現,這將使您完全擺脫動態類加載。 此機制是OSGi固有的,它為上述自定義機制提供了非常優雅的替代方法。 與上一節中介紹的方法相比,此方法的缺點是,它需要對代碼進行一些更深的更改,特別是如果它也應繼續在OSGi之外運行的話。

您需要考慮以下方面:

  • 在OSGi服務注冊表中注冊您的接口和實現。
  • 在運行時在使用它們的代碼中發現這些實現。

盡管您可以通過編程方式注冊服務,但在大多數情況下,您還是希望使用OSGi聲明式服務方法,因為它允許以純聲明性的方式將現有實現注冊為OSGi服務。 關于發現,您可以直接通過BundleContext提供的功能查詢服務注冊表,也可以使用功能更強大的服務跟蹤器機制 。
關于OSGi服務,尤其是聲明式服務,有很多很棒的教程,其中包括:

  • OSGi服務– Lars Vogel的教程 。
  • OSGi入門: Neil Bartlett的聲明式服務簡介 。

就我們而言,我們不想太大地改變我們的代碼庫,因此我們只在少數幾個我們認為積極影響可以證明投資合理的地方改用OSGi服務。 目前,我們通過添加服務組件XML將現有的實現聲明為服務。 盡管這種基于XML的方法是標準且常用的方法,但我們發現它相當冗長且不便。 另一種方法是使用注釋來指定組件和服務,如聲明性服務Wiki頁面和OSGi Release 4 Draft Paper中所述 。 BND已經支持這些注釋。

其他注意事項

所有包裝僅以一捆出口

從多個捆綁包中導出同一軟件包在OSGi中效果不佳,因此必須避免。 如果您的代碼中包含這種情況,則應適當地重命名這些軟件包。

公開OSGi入口點

最后,您可能需要提供一個新的入口點,以便從OSGi控制臺啟動您的應用程序。 如果使用Equinox,則一種合適的機制是創建一個Equinox應用程序 ,該應用程序包括實現org.eclipse.equinox.app.IApplication接口并提供一個附加的plugin.xml,如Eclipse插件入門:命令中所述。在線應用程序 。 可以使用startApp命令從Equinox OSGi控制臺啟動此應用程序。

結論

通過遵循本文中介紹的準則和方法,可以使普通的Java應用程序和庫OSGi兼容,而對您現有代碼的投入卻相對較小,而且可管理。

您在使Java代碼與OSGi兼容方面有類似的經驗嗎? 如果是的話,我很想聽聽。

參考:通過我們的JCG合作伙伴 Stoyan Rachev的Stoyan Rachev博客博客,可以使Java Old Java OSGi兼容 。

翻譯自: https://www.javacodegeeks.com/2012/11/making-plain-old-java-osgi-compatible.html

總結

以上是生活随笔為你收集整理的使普通的旧Java OSGi兼容的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产亚洲三级 | 欧美一级大黄 | 天堂av免费在线观看 | 亚洲一区精品在线观看 | 狠狠狠狠狠 | 一本到在线视频 | 夜夜操免费视频 | 午夜视频免费在线 | 欧美日韩人妻精品一区在线 | 亚洲国产精品人人爽夜夜爽 | 久久久人妻无码一区二区 | 天堂久久av| 色婷婷婷婷色 | 久久精品久久久久 | 天天干,天天操,天天射 | 国模小丫大尺度啪啪人体 | japanese强行粗暴 | 国产做爰xxxⅹ高潮视频12p | 国产麻豆自拍 | 国产亚洲性欧美日韩在线观看软件 | 欧美精品一区二区三区久久 | 久久精品国产亚洲av高清色欲 | 免费久久久久久 | 国产亚洲二区 | 免费观看的毛片 | 女优中文字幕 | 欧美群交射精内射颜射潮喷 | 亚洲女人天堂色在线7777 | 无码人妻丰满熟妇啪啪 | 最新中文在线视频 | 欧美 日韩 国产 成人 在线观看 | 国产美女流白浆 | 午夜极品视频 | 少妇又色又紧又大爽又刺激 | 爱爱精品 | 国产制服91一区二区三区制服 | 美女福利一区 | 麻豆精品在线观看 | 久婷婷 | 亚洲老女人 | 特大黑人娇小亚洲女 | 中文字幕高清一区 | 一卡二卡三卡四卡五卡 | 日韩精品高清在线 | 毛片精品| 亚洲第一免费 | 亚洲一区二区福利 | 天天操夜夜爱 | 国产视频成人 | 91香蕉一区二区三区在线观看 | 强开小受嫩苞第一次免费视频 | 国产男女激情 | 中文字幕一区二区三区在线观看 | 欧美 日韩 国产 成人 在线 | 韩国日本中文字幕 | 777久久| 一区二区在线观看免费 | 高跟鞋调教—视频|vk | 日韩一区二区三区在线播放 | 丝袜老师扒开让我了一夜漫画 | 九九精品影院 | 久久久久九九九 | 99国产精品久久久久99打野战 | 国产在线观看免费 | 国产精品极品白嫩 | 日日摸日日干 | 91色影院 | 成 人片 黄 色 大 片 | 午夜私人影院 | 亚洲va视频 | 亚洲一区动漫 | 精品视频免费在线观看 | 亚洲天堂手机在线观看 | 欧美8888| 色婷婷精品久久二区二区密 | 红桃成人网 | eeuss一区二区 | 韩国av在线播放 | 无码熟妇人妻av | 99精品视频在线播放免费 | 一级做a爱片久久毛片 | 国产精品尤物 | 国产淫片av片久久久久久 | 特一级黄色片 | 欧美视频中文字幕 | 亚洲乱码国产乱码精品精 | 国产美女无遮挡永久免费观看 | 日本熟妇毛茸茸丰满 | 无码一区二区三区在线观看 | japanesexxxx日本妞 | 久久久久久久久久久久久久久久久久久 | 黄a网站 | 一区二区三区伦理片 | 69精品人妻一区二区三区 | 2021毛片| 中文字幕日韩精品亚洲一区小树林 | 无码精品一区二区三区在线播放 | 一本综合久久 | 国产三级视频 |