WAR文件与具有嵌入式服务器的Java应用程序
大多數(shù)服務(wù)器端Java應(yīng)用程序(例如,面向Web或面向服務(wù)的)都希望在容器中運(yùn)行。 打包這些應(yīng)用程序以進(jìn)行分發(fā)的傳統(tǒng)方法是將它們捆綁為WAR文件。 這無(wú)非是具有標(biāo)準(zhǔn)目錄布局的ZIP歸檔文件,其中包含運(yùn)行時(shí)所需的所有庫(kù)和應(yīng)用程序級(jí)依賴項(xiàng)。 這種格式幾乎可以互操作,并且可以部署到您喜歡的任何服務(wù)器容器,Tomcat或Jetty,JBoss或GlassFish等。
但是,還有另一種流派完全顛覆了這種模式。 通過(guò)這種方法,Java應(yīng)用程序像任何普通應(yīng)用程序一樣被打包用于命令行執(zhí)行。 嵌入式容器不是部署到容器,而是部署在應(yīng)用程序本身中!
這對(duì)于使用多種語(yǔ)言的課程來(lái)說(shuō)是一樣的。 適用于Python的Django框架包括用于開(kāi)發(fā)和測(cè)試的捆綁服務(wù)器,而Ruby on Rails附帶了一個(gè)用于生產(chǎn)的嵌入式服務(wù)器。 這個(gè)概念在Java中已經(jīng)存在了一段時(shí)間, Jetty專攻嵌入式利基市場(chǎng)。 但是,這與規(guī)范相去甚遠(yuǎn),事實(shí)上的標(biāo)準(zhǔn)仍然是可以部署到Tomcat的WAR文件。
但是,嗡嗡聲越來(lái)越大。 在去年的DevNexus會(huì)議上,我參加了James Ward的會(huì)議,當(dāng)時(shí)他是Heroku的“開(kāi)發(fā)者”。 捆綁您自己的容器是將應(yīng)用程序部署到Heroku的基于云的平臺(tái)的推薦方法,而James是一個(gè)大力支持者 。
他的會(huì)議專門(mén)針對(duì)Java和Scala的Play框架,該框架以類似于Rails服務(wù)器的方式嵌入Netty 。 與Grails不同, Grails使用Django風(fēng)格的服務(wù)器進(jìn)行開(kāi)發(fā),然后將其作為WAR文件發(fā)布,而Play則打算在生產(chǎn)過(guò)程中一直使用自己的服務(wù)器。 James在所有Java應(yīng)用程序中都倡導(dǎo)了這種方法。
一場(chǎng)嵌入式冒險(xiǎn)
我至少喝了一口Kool-Aid。 當(dāng)我開(kāi)始編寫(xiě)示例Hibernate Search by Example時(shí) ,我想將重點(diǎn)放在Hibernate Search上,而不是其他任何框架或服務(wù)器問(wèn)題上。 因此,我避開(kāi)了Spring,并使用普通的Servlet 3.0方法編寫(xiě)了本書(shū)的示例應(yīng)用程序。
我通常在自己的開(kāi)發(fā)環(huán)境中使用Eclipse,并將其指向本地Tomcat實(shí)例以測(cè)試Web應(yīng)用程序。 但是,我想為喜歡使用IntelliJ,Netbeans或根本不使用IDE的讀者提供支持。 因此,我決定將構(gòu)建腳本嵌入測(cè)試服務(wù)器,以便讀者可以運(yùn)行示例而無(wú)需安裝或配置任何東西。
在Maven中使用嵌入式服務(wù)器
我的第一個(gè)目標(biāo)只是從我的Maven構(gòu)建腳本中啟動(dòng)服務(wù)器,因此讀者不必安裝服務(wù)器或?qū)⑵浼傻絀DE中。 我以前看過(guò)這件事,這很簡(jiǎn)單,只需將Jetty Maven插件添加到項(xiàng)目的POM中即可。 讀者應(yīng)該能夠使用以下命令構(gòu)建示例應(yīng)用程序并一步啟動(dòng)它:
mvn clean jetty:run嗯,不是那么快。 您應(yīng)該能夠?qū)o態(tài)內(nèi)容進(jìn)行更改,并看到更改在服務(wù)器運(yùn)行時(shí)立即生效。 但是,我遇到了有關(guān)文件被鎖定的錯(cuò)誤。 在花了一些時(shí)間進(jìn)行研究之后,我發(fā)現(xiàn)Jetty的默認(rèn)設(shè)置在Windows文件鎖定中效果不佳。 可以通過(guò)在一個(gè)配置文件中切換一個(gè)屬性來(lái)解決此問(wèn)題。
但是,您必須打開(kāi)Jetty JAR文件才能獲取此配置文件的正確副本。 首先,你要挖圍繞本地Maven回購(gòu),并找出哪些 JAR文件破解打開(kāi)(它原來(lái)是碼頭,web應(yīng)用,而不是碼頭服務(wù)器)。 一旦獲得了webdefault.xml文件的副本并切換了useFileMappedBuffer設(shè)置,就必須將副本保存在項(xiàng)目中的某個(gè)位置,并更新Maven POM以在此處查找而不是在Jetty JAR內(nèi)部查找:
<plugin><groupId>org.mortbay.jetty</groupId><artifactId>jetty-maven-plugin</artifactId><version>8.1.7.v20120910</version><configuration><webAppConfig><defaultsDescriptor>${basedir}/src/main/webapp/WEB-INF/webdefault.xml</defaultsDescriptor></webAppConfig></configuration> </plugin>好吧……比我預(yù)期的麻煩得多,但是我可以解決這個(gè)問(wèn)題。
將嵌入式服務(wù)器與其他構(gòu)建系統(tǒng)一起使用
我知道許多Java開(kāi)發(fā)人員都討厭Maven。 因此,我想提供使用Ant構(gòu)建的本書(shū)示例應(yīng)用程序的版本,以說(shuō)明如何適應(yīng)默認(rèn)概念。 那么,我應(yīng)該在build.xml中添加哪一行以使Ant使用Jetty?
嗯,不是那么快。 有 用于碼頭Ant集成 ,但它比Maven的更繁瑣。 即使您使用的是Ivy之類的依賴項(xiàng)管理系統(tǒng),您的Ant腳本也無(wú)法為您下載和管理嵌入式服務(wù)器。 相反,您必須下載完整的獨(dú)立Jetty服務(wù)器,然后手動(dòng)將其片段復(fù)制到您的項(xiàng)目中。 誰(shuí)不希望將6兆的可執(zhí)行二進(jìn)制文件提交到源代碼管理中?
在Jetty服務(wù)器JAR上復(fù)制后,您需要手動(dòng)添加另一個(gè)JAR文件以進(jìn)行Ant集成。 令我驚訝的是,我發(fā)現(xiàn)最新的受支持版本是Jetty 7,實(shí)現(xiàn)了將近8年的Servlet 2.5規(guī)范。
我看到他們終于在上個(gè)月添加了Jetty 8,但是當(dāng)我去年秋天寫(xiě)這本書(shū)時(shí),這對(duì)我沒(méi)有幫助。 我不得不為Servlet 2.5(而不是3.0)重寫(xiě)這個(gè)示例應(yīng)用程序版本,并且開(kāi)始懷疑這是否真的值得。
通過(guò)代碼使用嵌入式服務(wù)器
本書(shū)的最后這一章討論了在集群服務(wù)器環(huán)境中運(yùn)行的Hibernate Search應(yīng)用程序。 Maven插件純粹是單實(shí)例的,因此我決定編寫(xiě)一個(gè)小的引導(dǎo)程序類,該類將在語(yǔ)法上在不同端口上啟動(dòng)兩個(gè)Jetty實(shí)例。 通過(guò)將此類構(gòu)造為JUnit測(cè)試,我仍然可以讓Maven像這樣自動(dòng)啟動(dòng)它:
嗯,不是那么快。 啟動(dòng)時(shí)未注冊(cè)我的應(yīng)用程序的Servlet,偵聽(tīng)器和RESTful服務(wù)。 經(jīng)過(guò)大量浪費(fèi)的研究時(shí)間后,我發(fā)現(xiàn)有很多不同的Jetty “風(fēng)味”可用,默認(rèn)情況下啟用或禁用Servlet 3.0功能(例如注釋)。
老實(shí)說(shuō),我仍然不完全了解如何分辨“高潮”和“非高潮”之間的區(qū)別。 我只能告訴您的是,為了使注釋能夠正常工作,我必須將這段代碼添加到我的bootstrap類中:
... masterContext.setConfigurations( new Configuration[] { new WebInfConfiguration(), new WebXmlConfiguration(), new MetaInfConfiguration(), new FragmentConfiguration(), new EnvConfiguration(), new PlusConfiguration(), new AnnotationConfiguration(), new JettyWebXmlConfiguration(), new TagLibConfiguration() } ); ...比將WAR文件拖放到Tomcat的/ webapps文件夾中更簡(jiǎn)單,更直觀,對(duì)嗎?
從控制臺(tái)和云使用嵌入式服務(wù)器
完成本書(shū)后,我希望將示例代碼的演示版本推送到GitHub并部署到Heroku 。 從理論上講,Heroku可以運(yùn)行可以從命令行在本地運(yùn)行的任何應(yīng)用程序。 如果Heroku找到Maven POM,它將運(yùn)行mvn clean程序包,然后執(zhí)行您在名為Procfile的腳本中放置的所有啟動(dòng)命令。
我的程序化Jetty啟動(dòng)器在Maven運(yùn)行的情況下運(yùn)行良好。 但是,Maven在測(cè)試時(shí)正在管理我的類路徑依賴項(xiàng),現(xiàn)在我需要在沒(méi)有該幫助的情況下可以使用Jetty。 Heroku在其演示Java應(yīng)用程序中使用的推薦方法是將您的應(yīng)用程序與Tomcat的一個(gè)文件版本捆綁在一起。 太棒了,無(wú)論如何,我還是更熟悉Tomcat!
嗯,不是那么快。 如果您的應(yīng)用程序希望將數(shù)據(jù)庫(kù)連接(或其他任何內(nèi)容)注冊(cè)為JNDI資源,那么您就自己決定了。 Heroku捆綁的Tomcat運(yùn)行程序不支持JNDI設(shè)置。 嗯......也許這就是為什么Heroku的香草servlet的演示并沒(méi)有真正做什么,以及為什么只演示應(yīng)用程序, 并做一些事情,而不是是基于Spring。 現(xiàn)在,我考慮了一下,James Ward去年離開(kāi)了Heroku,為T(mén)ypeSafe工作,自從他離開(kāi)后,Heroku就沒(méi)有對(duì)其Java網(wǎng)站進(jìn)行任何更新。 喝了
不用擔(dān)心,因?yàn)橛幸粋€(gè)類似的單文件Jetty Runner ,它確實(shí)允許您將JNDI設(shè)置作為命令行參數(shù)傳遞。 此外,我們已經(jīng)投入了大量時(shí)間來(lái)解決嵌入式Jetty的所有問(wèn)題!
嗯,還是太快了。 如果您在JSP視圖中使用JSTL taglib(即您生活在21世紀(jì)),那么Jetty Runner會(huì)讓您陷入混亂 。 從命令行運(yùn)行它時(shí),您需要將參數(shù)傳遞給Java,以實(shí)現(xiàn)以下目的:
(*)您沒(méi)看錯(cuò)。 經(jīng)過(guò)所有這些嵌入式噩夢(mèng)之后,Heroku 實(shí)際上仍在使用WAR文件 !
我的Heroku個(gè)人資料最終看起來(lái)像這樣:
web: java $JAVA_OPTS -jar target/dependency/jetty-runner-8.1.7.v20120910.jar --lib target/hibernate-search-demo-0.0.1-SNAPSHOT/WEB-INF/lib --port $PORT --jdbc org.apache.commons.dbcp.BasicDataSource "url=jdbc:h2:mem:vaporware;DB_CLOSE_DELAY=-1" "jdbc/vaporwareDB" target/*.war這里有多個(gè)類加載器在工作,這使Jetty Runner可以從其類路徑而不是Web應(yīng)用程序的類路徑加載JSTL / taglib東西。
結(jié)論
從一開(kāi)始就將嵌入式服務(wù)器概念嵌入框架中,嵌入式服務(wù)器概念就沒(méi)有本質(zhì)上的錯(cuò)誤。 編寫(xiě)Play應(yīng)用程序是一種樂(lè)趣,將它們部署在Heroku上幾乎是微不足道的。 在日常工作中,我使用一個(gè)名為hybris的基于Spring的商務(wù)軟件包,該軟件包的擴(kuò)展構(gòu)建系統(tǒng)將Tomcat服務(wù)器捆綁到您的應(yīng)用程序中。 只要您不需要過(guò)多地定制構(gòu)建腳本,就可以正常工作。
另一方面,該概念對(duì)于廣泛的通用用途而言太脆弱和脆弱。 用管道將嵌入式服務(wù)器連接到普通Java應(yīng)用程序上純屬痛苦。 您也許可以堅(jiān)持別人的工作示例的安全性,但是當(dāng)您的應(yīng)用執(zhí)行任何不同的操作時(shí),您就可以自行解決損壞問(wèn)題。 將我的嵌入式冒險(xiǎn)帶入上面,并將其與使用Tomcat的“麻煩”進(jìn)行對(duì)比:
我獲得的唯一真正優(yōu)勢(shì)是能夠在Heroku上運(yùn)行演示的能力。 但是,來(lái)自云提供商的Java支持每天都在提高。 Jelastic允許您立即將普通的WAR文件部署到Tomcat 7或GlassFish 3。 AppFog支持部署到Tomcat 6 ,即將支持Tomcat 7 。 我懷疑在不久的將來(lái), 修改應(yīng)用程序以進(jìn)行云部署的想法將被視為不合時(shí)宜。
簡(jiǎn)而言之,這取決于您使用的框架。 如果嵌入式服務(wù)器是嵌入式的,那么它們可能會(huì)很酷。 如果將它們用膠帶固定,則可能會(huì)很可怕。 如果我今天寫(xiě)的是Hibernate Search by Example ,示例應(yīng)用程序構(gòu)建腳本將產(chǎn)生兩件事:一個(gè)WAR文件和一個(gè)Tomcat下載鏈接。
翻譯自: https://www.javacodegeeks.com/2014/03/war-files-vs-java-apps-with-embedded-servers.html
總結(jié)
以上是生活随笔為你收集整理的WAR文件与具有嵌入式服务器的Java应用程序的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 缘去掉绞丝旁是什么字 缘去掉绞丝旁是彖吗
- 下一篇: 长方形体积公式是什么 关于长方形体积公式