jboss fuse 教程_JBoss Fuse –一些鲜为人知的技巧
jboss fuse 教程
TL; DR
將Java靜態(tài)調(diào)用公開為Karaf Shell本機(jī)命令
作為必須與支持人員和客戶進(jìn)行協(xié)作的軟件工程師的一部分,我經(jīng)常發(fā)現(xiàn)自己需要從無法訪問的系統(tǒng)中提取其他信息。 通常適用于所有軟件的方法通常是提取日志,調(diào)用交互式命令以獲得特定輸出,或者在最復(fù)雜的情??況下,部署一些PoC單元來驗證特定行為。
JBoss Fuse和Karaf所基于的平臺在公開所有這些數(shù)據(jù)方面做得非常好。
你有:
- 大量日志并與Log4j集成
- jmx操作的詳盡列表(您最終可以使用jolokia通過http調(diào)用)
- 大量的Shell命令
但是有時候這還不夠。 如果您看過我以前有關(guān)如何在JBoss Fuse上使用Byteman的文章,則可以想象所有其他情況:
Byteman仍然是一個很好的選擇,但是Karaf具有我們可以用來運(yùn)行自定義代碼的功能 。
Karaf,允許您直接在其shell中編寫代碼; 并允許您將這些代碼位記錄為可以重新調(diào)用的宏。 這個宏看起來像一個原生的Karaf shell命令!
讓我們看一個我必須實現(xiàn)的真實示例:
驗證運(yùn)行我的JBoss Fuse實例的jvm是否正在按預(yù)期解析特定的DNS。
標(biāo)準(zhǔn)JDK具有可用來解析dns名稱的方法: InetAddress.gettAllByName(String)
由于該命令非常簡單,這意味著它不需要復(fù)雜或結(jié)構(gòu)化的輸入,我想我可以將其變成易于重用的命令:
# add all public static methods on a java class as commands to the namespace "my_context": # bundle 0 is because system libs are served by that bundle classloader addcommand my_context (($.context bundle 0) loadClass java.net.InetAddress)該時髦的行用以下方式解釋:
- addcommand是接受新命令的karaf shell功能
- my_context是您要附加命令的名稱空間/前綴。 就我而言,“ dns”將成為一個好的名稱空間。 ($.context bundle 0)調(diào)用Java代碼。 特別是,我們正在調(diào)用$.context實例,該實例是Karaf shell公開的內(nèi)置實例,用于暴露OSGi框架,該框架的類型為org.apache.felix.framework.BundleContextImpl ,并且正在調(diào)用其方法,稱為bundle傳遞它的參數(shù)0表示負(fù)責(zé)加載JDK類的OSGi類加載器的ID。 該調(diào)用返回org.apache.felix.framework.Felix的實例,可用于加載所需的特定類定義,即java.net.InetAddress 。
正如內(nèi)聯(lián)注釋所說, addcommand的調(diào)用公開了該類上的所有公共靜態(tài)方法 。 因此,現(xiàn)在允許我們調(diào)用這些方法,尤其是可以解析dns條目的方法:
JBossFuse:karaf@root> my_context:getAllByName "www.google.com" www.google.com/74.125.232.146 www.google.com/74.125.232.145 www.google.com/74.125.232.148 www.google.com/74.125.232.144 www.google.com/74.125.232.147 www.google.com/2a00:1450:4002:804:0:0:0:1014此功能在Karaf文檔頁面上進(jìn)行了描述。
在部署時覆蓋OSGi標(biāo)頭
如果您與Karaf合作,那么您正在與OSGi合作,喜歡或討厭它 。 每個OSGi工作流程中的典型步驟是使用OSGi標(biāo)頭 (或與之戰(zhàn)斗)。 如果您完全控制項目,則這可能會或多或少容易,具體取決于部署單元之間的關(guān)系。 請參閱Christian Posta的帖子 ,以瞥見一些不明顯的例子。
在這些情況下,一種非常典型的情況是必須使用捆綁包,您自己的捆綁包或他人的捆綁包 ,并且捆綁包頭不正確 。 最終要做的通常是重新打包該捆綁包,以便您可以更改其MANIFEST的內(nèi)容 ,以添加所需的OSGi標(biāo)頭。
Karaf在這方面具有一種設(shè)施,稱為wrap協(xié)議。 您可能已經(jīng)知道,這是在Karaf上部署非捆綁jar的快捷方式,但實際上不僅限于此 。
顧名思義,它真正要做的就是包裝。 但是它可以包裹非捆綁包和捆綁包! 這意味著我們還可以使用它來更改我們將要安裝的已打包捆綁包的元數(shù)據(jù)。
讓我們舉個例子,再次從現(xiàn)實生活中獲得經(jīng)驗。 Apache HttpClient并非完全OSGi友好。 我們可以使用wrap:協(xié)議將其安裝在Karaf上,并導(dǎo)出所有軟件包 。
JBossFuse:karaf@root> install -s 'mvn:org.apache.httpcomponents/httpclient/4.2.5' Bundle ID: 257 JBossFuse:karaf@root> exports | grep -i 257257 No active exported packages. This command only works on started bundles, use osgi:headers instead JBossFuse:karaf@root> install -s 'wrap:mvn:org.apache.httpcomponents/httpclient/\ 4.2.5$Export-Package=*; version=4.2.5' Bundle ID: 259 JBossFuse:karaf@root> exports | grep -i 259259 org.apache.http.client.entity; version=4.2.5259 org.apache.http.conn.scheme; version=4.2.5259 org.apache.http.conn.params; version=4.2.5259 org.apache.http.cookie.params; version=4.2.5 ...我們可以看到它也適用于普通捆綁包 :
JBossFuse:karaf@root> la -l | grep -i camel-core [ 142] [Active ] [ ] [ ] [ 50] mvn:org.apache.camel/camel-core/2.12.0.redhat-610379 JBossFuse:karaf@root> install -s 'wrap:mvn:org.apache.camel/camel-core/2.12.0.redhat-610379\ $overwrite=merge&Bundle-SymbolicName=paolo-s-hack&Export-Package=*; version=1.0.1' Bundle ID: 269JBossFuse:karaf@root> headers 269camel-core (269) ---------------- ...Bundle-Vendor = Red Hat, Inc. Bundle-Activator = org.apache.camel.impl.osgi.Activator Bundle-Name = camel-core Bundle-DocURL = http://redhat.com Bundle-Description = The Core Camel Java DSL based routerBundle-SymbolicName = paolo-s-hackBundle-Version = 2.12.0.redhat-610379 Bundle-License = http://www.apache.org/licenses/LICENSE-2.0.txt Bundle-ManifestVersion = 2...Export-Package = org.apache.camel.fabric;uses:="org.apache.camel.util,org.apache.camel.model,org.apache.camel,org.apache.camel.processor,org.apache.camel.api.management,org.apache.camel.support,org.apache.camel.spi";version=1.0.1,...在哪里可以看到Bundle-SymbolicName , 導(dǎo)出的軟件包的版本帶有我設(shè)置的值。
再次,該功能在Karaf文檔中進(jìn)行了描述,您可能會發(fā)現(xiàn)包裝協(xié)議參考非常有用。
在使用OSGi片段部署時間后覆蓋OSGi標(biāo)頭
最后一個技巧很強(qiáng)大,但是如果您不想冒險讓一個類加載器暴露一半的類,而讓另一個類加載器暴露剩余的類(那些您可能已經(jīng)在重寫的Export添加的包),則可能需要您刪除原始包。之一。
實際上,有一種更好的方法來覆蓋OSGi標(biāo)頭,它直接來自O(shè)SGi標(biāo)準(zhǔn)功能: OSGi Fragments 。
如果您不熟悉此概念,則直接取自O(shè)SGi Wiki的定義是:
捆綁包片段,或簡稱為片段,是一個捆綁包,其內(nèi)容可用于另一個捆綁包(片段主機(jī))。 重要的是,片段共享其父捆綁的類加載器。
該頁面還提供了有關(guān)我將要描述的內(nèi)容的進(jìn)一步提示:
有時,片段用于“修補(bǔ)”現(xiàn)有的捆綁包。
我們可以使用此策略來:
- 在目標(biāo)包的類路徑中注入.jars
- 更改目標(biāo)包的標(biāo)題
我用第一種情況來修復(fù)配置錯誤的捆綁包,該捆綁包正在尋找一個不包含它的xml配置描述符,并且我提供了部署包含此內(nèi)容的輕型Fragment Bundle。
但是我想在這里向您展示的用例是對在JBoss Fuse / Karaf上部署B(yǎng)yteman的方式的一種改進(jìn) 。
如果你還記得我以前的帖子 ,因為Byteman類需要可從所有其他部署包,并可能需要提供訪問每一個類,我們不得不Byteman包添加到org.osgi.framework.bootdelegation屬性,指示OSGi框架通過虛擬系統(tǒng)捆綁包(id = 0)公開列出的軟件包 。
您可以使用headers 0來驗證當(dāng)前正在使用的內(nèi)容,因為它是jdk擴(kuò)展和框架類的一長串,所以這里不包括輸出。
如果添加我的包org.jboss.byteman.rule,org.jboss.byteman.rule.exception ,即使這些包也會在該命令的輸出中列出。
該解決方案的問題在于這是引導(dǎo)時間屬性 。 如果要使用Byteman操作已經(jīng)運(yùn)行的實例的字節(jié)碼,則必須在編輯此屬性后重新啟動它。
OSGi片段可以在這里提供幫助,并避免在引導(dǎo)時進(jìn)行預(yù)配置。
我們可以構(gòu)建一個沒有實際內(nèi)容的自定義空捆綁包,該捆綁包將附加到系統(tǒng)捆綁包并擴(kuò)展其服務(wù)的包列表。
<Export-Package>org.jboss.byteman.rule,org.jboss.byteman.rule.exception </Export-Package> <Fragment-Host>system.bundle; extension:=framework </Fragment-Host>這是maven-bundle-plugin插件配置的摘錄,有關(guān)完整的Maven項目 ,請參見此處,盡管該項目實際上只是pom.xml 30行:
JBossFuse:karaf@root> install -s mvn:test/byteman-fragment/1.0-SNAPSHOT一旦有了該配置,就可以使用Byteman,例如,在java.lang.String默認(rèn)構(gòu)造函數(shù)中插入一行。
# find your Fuse process id PROCESS_ID=$(ps aux | grep karaf | grep -v grep | cut -d ' ' -f2)# navigate to the folder where you have extracted Byteman cd /data/software/redhat/utils/byteman/byteman-download-2.2.0.1/# export Byteman env variable: export BYTEMAN_HOME=$(pwd) cd bin/# attach Byteman to Fabric8 process, no output expected unless you enable those verbose flags sh bminstall.sh -b -Dorg.jboss.byteman.transform.all $PROCESS_ID # add these flags if you have any kind of problem and what to see what's going on: -Dorg.jboss.byteman.debug -Dorg.jboss.byteman.verbose# install our Byteman custom rule, we are passing it directly inline with some bash trick sh bmsubmit.sh /dev/stdin <<OPTS# smoke test rule that uses also a custom output file RULE DNS StringSmokeTest CLASS java.lang.String METHOD <init>() AT ENTRY IF TRUE DO traceln(" works: " ); traceOpen("PAOLO", "/tmp/byteman.txt"); traceln("PAOLO", " works in files too " ); traceClose("PAOLO"); ENDRULEOPTS現(xiàn)在,要驗證Byteman是否正常工作,我們只需在Karaf shell中調(diào)用java.lang.String構(gòu)造函數(shù)即可:
JBossFuse:karaf@root> new java.lang.Stringworks:按照我們的規(guī)則,您還將在/tmp/byteman.txt看到內(nèi)容
第三個技巧的靈感來自O(shè)SGi Wiki和Spring的這個有趣的頁面 。
翻譯自: https://www.javacodegeeks.com/2015/02/jboss-fuse-less-known-trick.html
jboss fuse 教程
總結(jié)
以上是生活随笔為你收集整理的jboss fuse 教程_JBoss Fuse –一些鲜为人知的技巧的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: drools6.5_Drools 6.2
- 下一篇: cisco qos限速设置步骤图