因胸联盟 发表于 2015-1-18 11:23:42

JAVA网页设计GlassFish OSGi-JavaEE(二):深切了解OSGi WEB使用程序标准和GlassFish OSGi/WEB容 ...

用winrar打包j2ee的程序和用IDE打包应用程序是一样的。按照你的想法,你是不是也希望服务器都整合由一家公司提供呢?在Part1中,我们提到了企业级OSGi制订了一系列的标准来与JavaEE集成,个中,最具代表性的标准是OSGiWEB使用程序标准,这部分将率领人人深切了解OSGiWEB使用程序标准和GlassFishOSGi/WEB容器。本文将分红以下几个部分:


[*]了解OSGiWEB使用程序标准
[*]构建一个OSGiWEB使用程序
[*]利用GlassFish4部署OSGiWEB使用程序
[*]深切分析GlassFishOSGi/WEB容器
[*]思索
了解OSGiWEB使用程序标准

为何必要OSGiWEB

在信息和收集兴旺的明天,WEB使用程序已十分得盛行和广泛,一些义务关头型(Mission-Critical)的WEB使用程序天天都在高负荷地运转,很少有中止,由于一次不经意的中止大概形成数据的年夜范围丧失,以致丧失大批的资金而形成严峻的成果。这些义务关头型的WEB使用常常呈现在证券和股票等相干的金融行业。如今,我们入手下手思索一个场景:几个礼拜大概几个月乃至几年后,WEB使用的客户大概供应商但愿在WEB前端增添一些新的模块或功效,可是,为了增添这些新的模块,我们不克不及中断WEB使用,并且也不但愿再次重构大概改动WEB使用的现有架构和模块。这听起来难以想象,关于如许一个场景,最少应当中断使用程服务的实例吧。可是,客户不会允许。另外一方面,在现今年夜数据的时期,每秒钟城市有大批的数据进进我们的使用当中。那末,怎样办理如许的场景?
一个可行的谜底是:利用OSGiWEB构建我们的使用。






WAB-OSGiWEB的中心

复杂地说,OSGiWEB使用程序标准(chapter128intheOSGiEnterpriseRelease5Specification)界说了OSGiWEB的全体内容。关于OSGiWEB使用程序,典范情形下,它由一个WEB使用程序Bundle(即WebApplicationBundle,简称为WAB)所组成。
因而,起首我们必要了解WAB和和WAR的区分。
WAB简述


在Part1中,我们已提到Bundle是OSGi中的基础部署和办理实体。以是,WAB起首是一个Bundle,必需供应成为Bundle的OSGi元数据(如,Bundle-SymbolicName,Bundle-Version…),其次,WAB与JavaEE中的WAR一样,仍然是服务于WEB使用程序,可以利用Servlet2.5或更高版本的Servlet标准,因而,WAB必需包括可会见的WEB内容,详细的说,JavaServlet标准界说了一个WEB使用程序的布局并界说了一个基于JAR的文件格局(WAR),WAB必需包括WAR中的静态和静态的内容。
进一步地,要成为一个WAB,必要在MANIFEST.MF文件中经由过程Import-Package来形貌它的依附,比方:经由过程导进javax.servlet来利用Servlet的功效,别的,假如必要向外界供应服务,它也要经由过程Export-Package来导出服务地点的包。
我们可以经由过程分歧的体例来安装WAB,比方,经由过程撑持企业级OSGi的使用服务器所供应的命令行把持台(如,GlassFishAdminCLI),也能够经由过程程序的体例挪用OSGi底层API来安装WAB(如,BundleContext.installBundle)。不管哪种体例,WAB安装后,它的性命周期办理就像OSGi运转时的其他Bundle一样。只不外WAB的性命周期被一个WebExtender跟踪,一旦WAB筹办服务WEB哀求时,WebExtender必要将WAB中可会见的WEB内容部署到WEB运转时。今后当WAB不再服务WEB哀求时,WebExtender也必要将这些可会见的WEB内容从WEB运转时卸载失落。
关于WAB的安装,有一点必要分外申明,一个WEB使用程序可以在开辟阶段经由过程工具(比方,Maven插件)被打包成WAB然落后行安装,大概这个WEB使用程序可以在Bundle安装阶段经由过程WebURLHandler对尺度WAR举行转换来通明地创立WAB。GlassFish4已完成了后一种机制,我将在后续章节具体论述。
关于WebExtender和WebURLHandler,它们都是OSGiWEB容器的一部分,我们将在前面章节具体论述。
从下面的叙说,我们已看到了安装WAB与安装一般Bundle的分明的分歧的地方:除安装WAB到OSGi运转时,还必要将WAB中可会见的WEB内容部署到WEB运转时。关于这一点,OSGiWEB使用程序标准界说了WAB的性命周期形态图,

<br>
:WAB的性命周期形态图
摘自:OSGiEnterpriseRelease5Specification
我们将在后续章节中深切论述中的每一个阶段。
WAB界说

WAB自己就是一个OSGiBundle,因而,关于尺度OSGiBundle的界说一样合用于WAB,可是,WAB与尺度OSGiBundle实质的区分在于:WAB必要在MANIFEST.MF中界说Web-ContextPath属性。Web-ContextPath属性界说了这个WEB使用程序会见的高低文路径(ContextPath),在WEB服务器上,这个WEB使用程序中一切可会见的资本都要相对这个高低文路径。比方,假如在MANIFEST.MF界说了以下Web-ContextPath属性,
Web-ContextPath:/uas那末会见这个WEB使用程序的URL老是相对http://host:port/uas,必要注重的是:Web-ContextPath属性的值老是以斜杠’/’入手下手。
当安装WAB时,除非Web-ContextPath属性呈现在MANIFEST.MF中且Web-ContextPath的值是一个无效的值,不然,WebExtender会以为这不是一个WAB,而视为一个一般的Bundle。
WAB布局和相干的OSGi元数据

下面已看到,除尺度OSGi元数据,WAB必需要在META-INF/MANIFEST.MF文件中界说Web-ContextPath属性。比方,以下是一个WAB的布局,

<br>
:一个WAB的布局示例
这个WAB界说的OSGi元数据以下所示,

<br>
:的WAB的OSGi元数据示例
在中,我们界说了一个WAB,这个WAB中有一个Servlet,被放在了WEB-INF/classes目次下,并且这个WAB有两个外部依附,lib1.jar和lib2.jar。当安装WAB时,为了使这些静态的内容都可以被Web服务器会见到,我们就必需在这个WAB的MANIFEST.MF中依照必定的划定规矩指定OSGi元数据,也就是所示的那样,


[*]指定一些必需的属性包含Bundle-ManifestVersion、Bundle-SymbolicName、Bundle-Version。Bundle-Name是可选的,这是一个汗青遗留的属性,你能够不必指定它,可是我一般也会指定这个属性,由于,Bundle-Name属性的值能够用来反应Bundle的用处。
[*]指定Import-Package属性,由于这个WAB正在利用Servlet,以是我们导进了Servlet相干的包。
[*]指定Bundle-ClassPath属性,这个属性十分主要,它界说了怎样加载外部的依附和WAB本身的类,我们把WEB-INF/classes/放在WEB-INF/lib/lib1.jar和WEB-INF/lib/lib2.jar的后面,如许做是为了和传统WAR文件搜刮类的按次分歧,复杂地说,优先搜刮WAB本身的Class,然后再搜刮依附的库文件。
[*]指定Web-ContextPath属性。
经由过程对MANIFEST.MF追加OSGi元数据,也再次申明了WAB利用OSGi性命周期和类/资本加载划定规矩而不是尺度JavaEE情况的加载划定规矩,这点相当主要。
WAB的性命周期

在中已提到了WAB的性命周期,细心地与尺度OSGiBundle的性命周期对照一下,你会发明,WAB的性命周期多了四个阶段(DEPLOYING、DEPLOYED、UNDEPLOYING和UNDEPLOYED)。
当一个WAB处于DEPLOYED阶段时,它已做好了筹办来服务行将到来的WEB哀求。处于DEPLOYED阶段也意味着这个WAB大概处于ACTIVE形态,大概处于STARTING形态(由于有一个怠惰的激活战略)。关于怠惰的激活战略,在《OSGiInAction》一书第9.3节“Startingbundleslazily”有出色的先容。
关于具有怠惰的激活战略的WAB来讲,WebExtender应当确保当服务WEB的静态内容(如图象资本、HTML和CSS等)时不克不及改动该WAB所处的形态,即仍旧使它处于STARTING形态。
从中,我们可以分明地看到,为了让WAB可以服务行将到来的WEB哀求,WAB必要从DEPLOYING迁徙到DEPLOYED阶段,WebExtender必需部署WAB中的WEB使用程序相干的类和资本到Web运转时。详细地,

[*]守候WAB处于ACTIVE形态或STARTING形态
[*]发送org/osgi/service/web/DEPLOYING事务
[*]考证Web-ContextPath属性的值没有和其他已被部署的WEB使用程序的高低文路径抵触,也就是说包管高低文路径的独一性。假如有抵触,那末部署WAB失利,WebExtender应当纪录下部署失利的日记。
[*]假如3的考证经由过程,那末依照以下的按次,Web运转时入手下手处置部署相干的细节,假如web.xml存在的话,它也会处置web.xml中的内容。

[*]为这个WEB使用程序创立一个Servlet高低文
[*]初始化设置的Servlet事务侦听器
[*]初始化设置的使用程序过滤器等

[*]注册Servlet高低文作为OSGi服务
[*]发送org/osgi/service/web/DEPLOYED事务关照以后的WAB已筹办好了,能够服务WEB哀求。
假如在org/osgi/service/web/DEPLOYED事务发送前的任什么时候候有非常或毛病产生,那末WAB的部署将失利。
中我们也可以发明,一旦不再必要该WAB服务Web哀求时,那末该WAB必要从DEPLOYED经由UNDEPLOYING迁徙到UNDEPLOYED阶段(UNDEPLOYING是一个暂态)。
有几种办法可以使WAB处于UNDEPLOYED阶段,
办法1:中断WAB
一旦吸收到WABSTOPPING事务,WebExtender必需立即从Web运转时中undeployWeb使用程序资本。Undeploy的次要步骤以下:

[*]发送org/osgi/service/web/UNDEPLOYING事务关照Web使用程序资本将被undeploy。
[*]从OSGi注册表中移往Servlet高低文。
[*]Web运转时必需让该Web使用程序中断服务哀求。
[*]Web运转时必需清算一切Web使用程序相干的资本,如占用的JAR,和清算ClassLoader制止内存泄露等。
[*]发送org/osgi/service/web/UNDEPLOYED事务。
办法2:卸载(Uninstall)WAB
除中断WAB,也可以经由过程从OSGi运转时中卸载WAB来undeploy对应的Web使用程序资本,undeploy步骤和办法1一样。
办法3:中断WebExtender
当中断WebExtender时,一切被部署的WAB都将被undeploy,可是,只管WAB被undeploy了,它任然处于ACTIVE形态。
从以上能够得出,WAB性命周期的四个特有形态分歧于尺度OSGiBundle的形态,WAB性命周期的特有形态其实不受OSGi性命周期层把持,不是尺度的OSGi形态,这些独有的形态仅仅由WebExtender把持。
关于WAB性命周期,在“深切分析GlassFishOSGi/WEB容器”中将再次论述。
别的,当你浏览OSGiEnterpriseRelease5Specification时,出格要注重不克不及将Uninstall和Undeploy等量齐观,只管在一些场所下这两个术语都可以了解为“卸载”。
OSGiWeb容器

最初我们来谈一下OSGiWeb容器,在下面的章节中我们已屡次提到了WebExtender,Web运转时和WebURLHandler。这些实体组成了OSGiWeb容器,而OSGiWeb容器是OSGiWeb标准的完成。依据OSGiWeb标准,OSGiWeb容器由以下三个实体组成:


[*]WebExtender
考证是不是为WAB而且跟踪WAB的性命周期,同时卖力部署WAB到Web运转时和undeploy一个被部署的WAB。

[*]Web运转时Web使用程序运转时情况,关于GlassFish来讲,Web运转时基于TomcatCatalina。

[*]WebURLHandler一个URLStreamHandler,这个URLStreamHandler可以处置webbundle:scheme,这个scheme可以被用来转换和安装WAR到OSGi运转时中,GlassFish4供应了一个新的特征,即经由过程完成这个URLStreamHandler在部署时主动转换和安装WAR到OSGi运转时。

构建一个OSGiWEB使用程序

回到入手下手提出的成绩场景,即怎样在一直止JVM的情形下,构建一个静态的Web使用程序?
以下的Sample使用程序源于我已经查询拜访的一个GlassFish成绩,先看一下需求,
成绩场景

我们但愿构建如许一个Web使用程序,当启动这个Web使用程序时,没有任何Web模块被加载,界面显现“Nomodulesavailable.”,然后,当部署一个Web模块后,在扫瞄器上点击革新按钮(不重启使用程序),这个Web模块随即呈现在界面上。
开辟工具

在本文中我将利用以下的一些工具来修建开辟情况,个中,依据团体的利用习气,你也大概利用NetBeans或IntelliJIDEA。


[*]JavaSE7
[*]Maven3.0.4
[*]EclipseKepler
使用程序架构


<br>
上面具体地申明一下,

[*]将要创立的使用程序分红Web前端,寄存模块接口的Core,和完成模块接口的各个模块。Web前端接纳JSF2+CDI,也就是利用JavaEECDIBean与JSF页面举行绑定。使用程序的每一个Web模块都必要完成Core中的模块接口。
[*]Web前端以WAB体例打包,Core和每一个模块打包成尺度OSGiBundle。
[*]每一个模块有一个OSGiActivator,一旦部署模块到GlassFishOSGi运转时,将起首实行模块的Activator办法来注册模块服务以便让Web前真个服务侦听器可以猎取到响应的模块服务。
[*]一旦Web前真个服务侦听器(ServiceListener)发明有新的模块被注册,那末该模块将被增加到使用程序Bean的模块汇合中,相似的,一旦发明既有的模块从OSGi服务注册表中删除,那末使用程序Bean的模块汇合将移除该模块。
修建开辟情况来创立使用程序

我们将利用Maven来一步一步地创立一个多模块的工程,我保举利用以下的体例来创立多模块的工程,关于这类体例的具体申明,你可以参考。
假定我利用Windows平台来创立Sample使用程序。

[*]创立Sample使用程序的ParentPom文件
运转Windows命令行,在以后的事情目次下,实行以下命令:
mvnarchetype:create-DgroupId=cn.fujitsu.com.tangyong-DartifactId=glassfish.wab.sample-DarchetypeArtifactId=maven-archetype-site-simple
乐成实行后,你会发明在以后事情目次下创立了一个“glassfish.wab.sample“目次,而且有一个pom.xml文件,这个文件就是Sample使用程序的ParentPom文件。

[*]设置Sample使用程序的ParentPom文件
翻开Sample使用程序的ParentPom文件,放进以下的内容,
<build><finalName>${project.artifactId}</finalName><pluginManagement><plugins><plugin><groupId>org.apache.felix</groupId><artifactId>maven-bundle-plugin</artifactId><!--2.2.0andabovehavenewbndwhichhaswabinstruction.2.3.4hasfewimportantbugfixes.--><version>2.3.4</version><extensions>true</extensions><configuration><supportedProjectTypes><supportedProjectType>ejb</supportedProjectType><supportedProjectType>war</supportedProjectType><supportedProjectType>bundle</supportedProjectType><supportedProjectType>jar</supportedProjectType></supportedProjectTypes><instructions><!--ReadallOSGiconfigurationinfofromthisoptionalfile--><_include>-osgi.properties</_include><!--Nopackagesareexportedbydefault.Havinganypatternisdangerous,asthepluginwilladdanypackagefoundindependencychainthatmatchesthepatternaswell.Sincethereisnoeasywaytohaveanincludefilterforjustlocalpackages,wedontexportanythingbydefault.--><Export-Package>!*</Export-Package></instructions></configuration>…</plugin>…</plugins></build><dependencyManagement><dependencies><dependency><groupId>org.osgi</groupId><artifactId>org.osgi.core</artifactId><version>4.2.0</version><scope>provided</scope></dependency>…</dependencies></dependencyManagement><dependencies><!--Addthethefollowingdependenciestoeverymoduletosaveuserfromaddingthemtoeveryone.--><dependency><groupId>org.osgi</groupId><artifactId>org.osgi.core</artifactId></dependency>…</dependencies>
以上内容基于https://svn.java.net/svn/glassfish~svn/trunk/fighterfish/sample/parent-pom/pom.xml,完全的POM文件内容,请参照https://github.com/tangyong/GlassFishOSGiJavaEESample/blob/master/glassfish.wab.sample
/pom.xml。
你必定会问,为何要放进这些内容?以下是几个主要的缘故原由:

[*]Maven工程的POM文件有很好的承继干系,就像面向对象的类计划一样,将子工程必要的一些共通插件(plugin)和共通的依附(dependency)放进到ParentPOM文件中老是很好的做法。

[*]为了构建WAB,我们放进maven-bundle-plugin,maven-war-plugin和为了编译Java源文件所必要的maven-compiler-plugin等。这里,必要说一下maven-bundle-plugin,这个插件的目标是将工程打包成尺度OSGiBundle的文件格局,其外部利用了bnd,bnd是由OSGi同盟前主席PeterKriens创立,用来简化开辟OSGiBundle的疾苦。从下面的maven-bundle-plugin的设置看,有一个中央必要出格申明:
<instructions><_include>-osgi.properties</_include><Export-Package>!*</Export-Package></instructions>上述的指令中,经由过程“_include”标签指定了一个设置OSGi元数据的文本文件,这个文本文件的地位相对以后Maven工程的根目次(你也能够自行设置它的地位),osgi.properties中的内容是一组指定OSGi元数据的划定规矩,以下是一个osgi.properties的示例:
Export-Package:sample.foo;sample.bar;version=${project.version}Import-Package:sample.car;resolution:=optional,*Bundle-SymbolicName:${project.groupId}.${project.artifactId}…关于具体的指定例则,请拜见。
这里也要出格申明一下,我们利用MavenWar插件的2.4版本而不是2.1版本,由于2.1版本在Windows平台上打包时,会天生两个web.xml文件。这个成绩一样呈现在fighterfish子工程的SampleParentPOM中,我将很快修复它。
Export-Package
在下面的maven-bundle-plugin的设置中,还呈现了<Export-Package>!*</Export-Package>,这个标签和标签值的寄义是,默许地,这个OSGiBundle不导出任何包,除非我们显现地在osgi.properties中指定“Export-Package”值。

[*]创立Core子工程
从Windows命令行进进“assfish.wab.sample“目次,实行以下命令:
mvnarchetype:create-DgroupId=cn.fujitsu.com.tangyong-DartifactId=glassfish.wab.sample.core
乐成实行后,你会发明在“glassfish.wab.sample“目次下创立了一个“glassfish.wab.sample.core“目次,进进“glassfish.wab.sample.core“目次并翻开pom.xml文件,你会发明以下内容已主动被增加了。
<parent><groupId>cn.fujitsu.com.tangyong</groupId><artifactId>glassfish.wab.sample</artifactId><version>1.0-SNAPSHOT</version></parent>然后,在“glassfish.wab.sample.core“目次下创立一个osgi.properties文件,内容以下:
Export-Package={local-packages};version=${project.version}如许的话,当构建终极Bundle时,Bundle将导出外部的带有工程版本的包。

[*]创立Web客户端子工程
相似3,实行以下命令:
mvnarchetype:create-DgroupId=cn.fujitsu.com.tangyong-DartifactId=glassfish.wab.sample.web-DarchetypeArtifactId=maven-archetype-webapp乐成实行后,你会发明在“glassfish.wab.sample“目次下创立了一个“glassfish.wab.sample.web“目次。然后,新建src/main/java和src/main/resources/META-INF目次。默许地,这两个目次不会被创立。
接着,在“glassfish.wab.sample.web“目次下创立一个osgi.properties文件,内容以下:
Web-ContextPath:/wabsample我指定了这个WAB的Web高低文路径为/wabsample,你也能够自行修正为其他的值。

[*]创立WEB模块1子工程
相似4,实行以下命令:
mvnarchetype:create-DgroupId=cn.fujitsu.com.tangyong-DartifactId=glassfish.wab.sample.module1-DarchetypeArtifactId=maven-archetype-webapp乐成实行后,你会发明在“glassfish.wab.sample“目次下创立了一个“glassfish.wab.sample.module1“目次。
然后,翻开该工程的pom文件,增加“glassfish.wab.sample.core“依附声明,
<dependency><groupId>cn.fujitsu.com.tangyong</groupId><artifactId>glassfish.wab.sample.core</artifactId><version>1.0-SNAPSHOT</version></dependency>
[*]创立WEB模块2子工程
相似5,这里就跳过。

[*]设置开辟情况
一旦这些Maven子工程工程创立乐成,我们将举行开辟情况的设置,进进编码阶段,以下的步骤形貌了怎样将Maven集成到Eclipse。假定我的Eclipse事情空间(Workspace)是“E:QCONWS“。

[*]修正Kepler中的M2_REPO变量
修正Kepler中的M2_REPO变量的目标是为了设置M2_REPO的值为你呆板上的Maven当地堆栈(LocalRepository)。默许地,Kepler中的M2_REPO变量的值为~/.m2/repository。详细的修正步骤能够参照。

[*]为Maven工程创立Eclipse相干的文件(如,.project文件)
从Windows命令行进进“glassfish.wab.sample“目次,实行以下命令:
mvneclipse:eclipse
然后将“glassfish.wab.sample“工程连同子工程导进到Eclipse中。假如统统乐成的话,在Eclipse中,应当看到相似以下的画面。

<br>
:乐成导进到Eclipse的Sample使用程序布局表示图


使用程序中心逻辑



[*]glassfish.wab.sample.core
新建一个名为“Module“的接口,该接口的界说以下:
<build><finalName>${project.artifactId}</finalName><pluginManagement><plugins><plugin><groupId>org.apache.felix</groupId><artifactId>maven-bundle-plugin</artifactId><!--2.2.0andabovehavenewbndwhichhaswabinstruction.2.3.4hasfewimportantbugfixes.--><version>2.3.4</version><extensions>true</extensions><configuration><supportedProjectTypes><supportedProjectType>ejb</supportedProjectType><supportedProjectType>war</supportedProjectType><supportedProjectType>bundle</supportedProjectType><supportedProjectType>jar</supportedProjectType></supportedProjectTypes><instructions><!--ReadallOSGiconfigurationinfofromthisoptionalfile--><_include>-osgi.properties</_include><!--Nopackagesareexportedbydefault.Havinganypatternisdangerous,asthepluginwilladdanypackagefoundindependencychainthatmatchesthepatternaswell.Sincethereisnoeasywaytohaveanincludefilterforjustlocalpackages,wedontexportanythingbydefault.--><Export-Package>!*</Export-Package></instructions></configuration>…</plugin>…</plugins></build><dependencyManagement><dependencies><dependency><groupId>org.osgi</groupId><artifactId>org.osgi.core</artifactId><version>4.2.0</version><scope>provided</scope></dependency>…</dependencies></dependencyManagement><dependencies><!--Addthethefollowingdependenciestoeverymoduletosaveuserfromaddingthemtoeveryone.--><dependency><groupId>org.osgi</groupId><artifactId>org.osgi.core</artifactId></dependency>…</dependencies>0
[*]glassfish.wab.sample.web
Web子工程的中心是ApplicationBean类,这也是一个CDIBean,而且和JSF页面绑定在一同,成了JSF托管Bean(ManagedBean)。以下是home.xhtml页面中与ApplicationBean相干的内容,
<build><finalName>${project.artifactId}</finalName><pluginManagement><plugins><plugin><groupId>org.apache.felix</groupId><artifactId>maven-bundle-plugin</artifactId><!--2.2.0andabovehavenewbndwhichhaswabinstruction.2.3.4hasfewimportantbugfixes.--><version>2.3.4</version><extensions>true</extensions><configuration><supportedProjectTypes><supportedProjectType>ejb</supportedProjectType><supportedProjectType>war</supportedProjectType><supportedProjectType>bundle</supportedProjectType><supportedProjectType>jar</supportedProjectType></supportedProjectTypes><instructions><!--ReadallOSGiconfigurationinfofromthisoptionalfile--><_include>-osgi.properties</_include><!--Nopackagesareexportedbydefault.Havinganypatternisdangerous,asthepluginwilladdanypackagefoundindependencychainthatmatchesthepatternaswell.Sincethereisnoeasywaytohaveanincludefilterforjustlocalpackages,wedontexportanythingbydefault.--><Export-Package>!*</Export-Package></instructions></configuration>…</plugin>…</plugins></build><dependencyManagement><dependencies><dependency><groupId>org.osgi</groupId><artifactId>org.osgi.core</artifactId><version>4.2.0</version><scope>provided</scope></dependency>…</dependencies></dependencyManagement><dependencies><!--Addthethefollowingdependenciestoeverymoduletosaveuserfromaddingthemtoeveryone.--><dependency><groupId>org.osgi</groupId><artifactId>org.osgi.core</artifactId></dependency>…</dependencies>1个中,#{applicationBean.modules}是JSF表达式言语,经由过程这个表达式,可以猎取到ApplicationBean类实例中的modules变量的值。在计划这个页面时,我们经由过程<ui:repeat>标签静态地追加<h:panelGrid>,一旦有新的模块到来大概既有模块被移除,ApplicationBean类实例中的modules变量的值将产生改动,然后,当革新扫瞄器时,JSF页面将出现出分歧的内容。
那末,ApplicationBean类实例是怎样跟踪到模块的注册和移除的呢?起首,让我们看一下ApplicationBean类的界说:
<build><finalName>${project.artifactId}</finalName><pluginManagement><plugins><plugin><groupId>org.apache.felix</groupId><artifactId>maven-bundle-plugin</artifactId><!--2.2.0andabovehavenewbndwhichhaswabinstruction.2.3.4hasfewimportantbugfixes.--><version>2.3.4</version><extensions>true</extensions><configuration><supportedProjectTypes><supportedProjectType>ejb</supportedProjectType><supportedProjectType>war</supportedProjectType><supportedProjectType>bundle</supportedProjectType><supportedProjectType>jar</supportedProjectType></supportedProjectTypes><instructions><!--ReadallOSGiconfigurationinfofromthisoptionalfile--><_include>-osgi.properties</_include><!--Nopackagesareexportedbydefault.Havinganypatternisdangerous,asthepluginwilladdanypackagefoundindependencychainthatmatchesthepatternaswell.Sincethereisnoeasywaytohaveanincludefilterforjustlocalpackages,wedontexportanythingbydefault.--><Export-Package>!*</Export-Package></instructions></configuration>…</plugin>…</plugins></build><dependencyManagement><dependencies><dependency><groupId>org.osgi</groupId><artifactId>org.osgi.core</artifactId><version>4.2.0</version><scope>provided</scope></dependency>…</dependencies></dependencyManagement><dependencies><!--Addthethefollowingdependenciestoeverymoduletosaveuserfromaddingthemtoeveryone.--><dependency><groupId>org.osgi</groupId><artifactId>org.osgi.core</artifactId></dependency>…</dependencies>2以上界说中,moduleListener饰演了主要的感化,moduleListener是org.osgi.framework.ServiceListener的一个完成,ServiceListener的感化是用来跟踪OSGi服务的注册,更新和卸载。afterAddModule和beforeRemoveModule作为回调办法被moduleListener挪用,详细地,moduleListener中注进了ApplicationBean实例,一旦有新的模块到来,moduleListener就会经由过程ApplicationBean实例来挪用afterAddModule办法,假如既有的模块被移除,那末就挪用beforeRemoveModule办法。
在glassfish.wab.sample.web中另有一些其他的类,由于篇幅干系,就纷歧一叙说了,具体地内容请拜见:https://github.com/tangyong/GlassFishOSGiJavaEESample/tree/master
/glassfish.wab.sample/glassfish.wab.sample.web

[*]glassfish.wab.sample.module1
模块1很复杂,只要两个类,完成Module接口的Module1类和BundleActivator的完成类Activator。我们必需要追加一个BundleActivator的完成类以便模块1在启动时可以将本人注册到GlassFishOSGi运转时的服务注册表中。
具体的内容请拜见:https://github.com/tangyong/GlassFishOSGiJavaEESample/tree/master
/glassfish.wab.sample/glassfish.wab.sample.module1

[*]glassfish.wab.sample.module2
相似于模块1,这里就省略跳过。
完全的Sample使用程序,请从https://github.com/tangyong/GlassFishOSGiJavaEESample中下载。

利用GlassFish4部署OSGiWEB使用程序

一旦我们构建完Sample使用程序,就将利用GlassFish4来部署它。
安装和启动GlassFish

起首,你必要从以下链接下载一个GlassFish4的安装zip包。然后解紧缩这个zip包到当地的文件体系。
http://download.java.net/glassfish/4.0/release/glassfish-4.0.zip
然后,经由过程以下命令,启动GlassFish的domain,默许地,GlassFish会为你创立好一个domain。假定解紧缩后的GlassFish地点的目次用$GlassFish_HOME暗示,
<build><finalName>${project.artifactId}</finalName><pluginManagement><plugins><plugin><groupId>org.apache.felix</groupId><artifactId>maven-bundle-plugin</artifactId><!--2.2.0andabovehavenewbndwhichhaswabinstruction.2.3.4hasfewimportantbugfixes.--><version>2.3.4</version><extensions>true</extensions><configuration><supportedProjectTypes><supportedProjectType>ejb</supportedProjectType><supportedProjectType>war</supportedProjectType><supportedProjectType>bundle</supportedProjectType><supportedProjectType>jar</supportedProjectType></supportedProjectTypes><instructions><!--ReadallOSGiconfigurationinfofromthisoptionalfile--><_include>-osgi.properties</_include><!--Nopackagesareexportedbydefault.Havinganypatternisdangerous,asthepluginwilladdanypackagefoundindependencychainthatmatchesthepatternaswell.Sincethereisnoeasywaytohaveanincludefilterforjustlocalpackages,wedontexportanythingbydefault.--><Export-Package>!*</Export-Package></instructions></configuration>…</plugin>…</plugins></build><dependencyManagement><dependencies><dependency><groupId>org.osgi</groupId><artifactId>org.osgi.core</artifactId><version>4.2.0</version><scope>provided</scope></dependency>…</dependencies></dependencyManagement><dependencies><!--Addthethefollowingdependenciestoeverymoduletosaveuserfromaddingthemtoeveryone.--><dependency><groupId>org.osgi</groupId><artifactId>org.osgi.core</artifactId></dependency>…</dependencies>3更多的关于GlassFish4的文档,请参考:http://glassfish.java.net/documentation.html
部署OSGi使用程序的体例

基础上,利用GlassFish4部署OSGi使用程序有三种体例,


[*]利用asadmindeploy命令
在命令行大概Shell中,利用相似以下的命令,
<build><finalName>${project.artifactId}</finalName><pluginManagement><plugins><plugin><groupId>org.apache.felix</groupId><artifactId>maven-bundle-plugin</artifactId><!--2.2.0andabovehavenewbndwhichhaswabinstruction.2.3.4hasfewimportantbugfixes.--><version>2.3.4</version><extensions>true</extensions><configuration><supportedProjectTypes><supportedProjectType>ejb</supportedProjectType><supportedProjectType>war</supportedProjectType><supportedProjectType>bundle</supportedProjectType><supportedProjectType>jar</supportedProjectType></supportedProjectTypes><instructions><!--ReadallOSGiconfigurationinfofromthisoptionalfile--><_include>-osgi.properties</_include><!--Nopackagesareexportedbydefault.Havinganypatternisdangerous,asthepluginwilladdanypackagefoundindependencychainthatmatchesthepatternaswell.Sincethereisnoeasywaytohaveanincludefilterforjustlocalpackages,wedontexportanythingbydefault.--><Export-Package>!*</Export-Package></instructions></configuration>…</plugin>…</plugins></build><dependencyManagement><dependencies><dependency><groupId>org.osgi</groupId><artifactId>org.osgi.core</artifactId><version>4.2.0</version><scope>provided</scope></dependency>…</dependencies></dependencyManagement><dependencies><!--Addthethefollowingdependenciestoeverymoduletosaveuserfromaddingthemtoeveryone.--><dependency><groupId>org.osgi</groupId><artifactId>org.osgi.core</artifactId></dependency>…</dependencies>4当部署WAB时,常常简单漏掉—type=osgi,假如漏掉这个选项,那末你所做的就是在部署一个尺度的WAR而不是WAB。

[*]利用autodeploy的体例
这是一个十分快速的部署体例,你只必要将要部署的Bundle放到$GlassFish_HOME/glassfish4/glassfish/domains/domain1/autodeploy/bundles目次下就能够了。这类体例是将ApacheFelixFileInstall集成到GlassFish中,利用这类体例乃至可以思索Bundle之间的依附。具体地内容,请看一下。

[*]利用asadminosgi命令
GlassFish3同意你经由过程telnet上岸到GlassFishOSGi运转时的背景,然后经由过程以下的体例来安装并启动一个WAB,
<build><finalName>${project.artifactId}</finalName><pluginManagement><plugins><plugin><groupId>org.apache.felix</groupId><artifactId>maven-bundle-plugin</artifactId><!--2.2.0andabovehavenewbndwhichhaswabinstruction.2.3.4hasfewimportantbugfixes.--><version>2.3.4</version><extensions>true</extensions><configuration><supportedProjectTypes><supportedProjectType>ejb</supportedProjectType><supportedProjectType>war</supportedProjectType><supportedProjectType>bundle</supportedProjectType><supportedProjectType>jar</supportedProjectType></supportedProjectTypes><instructions><!--ReadallOSGiconfigurationinfofromthisoptionalfile--><_include>-osgi.properties</_include><!--Nopackagesareexportedbydefault.Havinganypatternisdangerous,asthepluginwilladdanypackagefoundindependencychainthatmatchesthepatternaswell.Sincethereisnoeasywaytohaveanincludefilterforjustlocalpackages,wedontexportanythingbydefault.--><Export-Package>!*</Export-Package></instructions></configuration>…</plugin>…</plugins></build><dependencyManagement><dependencies><dependency><groupId>org.osgi</groupId><artifactId>org.osgi.core</artifactId><version>4.2.0</version><scope>provided</scope></dependency>…</dependencies></dependencyManagement><dependencies><!--Addthethefollowingdependenciestoeverymoduletosaveuserfromaddingthemtoeveryone.--><dependency><groupId>org.osgi</groupId><artifactId>org.osgi.core</artifactId></dependency>…</dependencies>5可是,到了GlassFish4,这类telnet的体例已被克制了,缘故原由是telnet的体例其实不平安,因而,GlassFish4供应了一种新的体例往间接操纵OSGi运转时,即经由过程实行asadminosgi...命令,比方,下面的命令同等于以下,
<build><finalName>${project.artifactId}</finalName><pluginManagement><plugins><plugin><groupId>org.apache.felix</groupId><artifactId>maven-bundle-plugin</artifactId><!--2.2.0andabovehavenewbndwhichhaswabinstruction.2.3.4hasfewimportantbugfixes.--><version>2.3.4</version><extensions>true</extensions><configuration><supportedProjectTypes><supportedProjectType>ejb</supportedProjectType><supportedProjectType>war</supportedProjectType><supportedProjectType>bundle</supportedProjectType><supportedProjectType>jar</supportedProjectType></supportedProjectTypes><instructions><!--ReadallOSGiconfigurationinfofromthisoptionalfile--><_include>-osgi.properties</_include><!--Nopackagesareexportedbydefault.Havinganypatternisdangerous,asthepluginwilladdanypackagefoundindependencychainthatmatchesthepatternaswell.Sincethereisnoeasywaytohaveanincludefilterforjustlocalpackages,wedontexportanythingbydefault.--><Export-Package>!*</Export-Package></instructions></configuration>…</plugin>…</plugins></build><dependencyManagement><dependencies><dependency><groupId>org.osgi</groupId><artifactId>org.osgi.core</artifactId><version>4.2.0</version><scope>provided</scope></dependency>…</dependencies></dependencyManagement><dependencies><!--Addthethefollowingdependenciestoeverymoduletosaveuserfromaddingthemtoeveryone.--><dependency><groupId>org.osgi</groupId><artifactId>org.osgi.core</artifactId></dependency>…</dependencies>6关于asadminosgi命令,最经常使用的就是,当你部署完一个OSGiBundle大概想看一下某些Bundle的Id大概以后形态时,利用asadminosgilb命令可以枚举出OSGi运转时中一切的Bundle。

关于这三种体例,我加倍偏向于利用“利用autodeploy的体例“,由于它加倍复杂,更无效率。关于“利用asadmindeploy命令”,尽年夜多半场所,实行的效力也很好,可是,当你的程序利用vaadin时,部署将会十分慢,这是GlassFish必要急需改善的一个特征,信任很快将会失掉改良。
部署并运转Sample使用程序

如今,我们能够依照以下的按次部署并运转Sample使用程序了,

[*]部署glassfish.wab.sample.core
实行“asadmindeploy&ndash;type=osgiglassfish.wab.sample.core.jar”

[*]部署glassfish.wab.sample.web.war
实行“asadmindeploy&ndash;type=osgiglassfish.wab.sample.web.war“

[*]在扫瞄器上键进“http://localhost:8080/wabsample/“,应当没有呈现任何模块,以下图所示,

<br>

[*]部署glassfish.wab.sample.module1和glassfish.wab.sample.module2
实行“asadmindeploy&ndash;type=osgiglassfish.wab.sample.module1.war“和”asadmindeploy&ndash;type=osgiglassfish.wab.sample.module2.war“

[*]在扫瞄器上点击革新按钮,此时,模块1和模块2都呈现了,以下图所示,

<br>
然后,再实行“asadminosgilb“命令看一下方才我们部署的Bundle的形态,

<br>

[*]实行以下命令卸载模块2
“asadminundeployglassfish.wab.sample.module2“

[*]然后,在扫瞄器上再次点击革新按钮,此时,模块2已消散了,以下图所示,

<br>

分析GlassFishOSGi/WEB容器

到这里为止,假如你细心浏览下面的内容,我想你应当已把握了怎样开辟和部署一个WAB,而且也应当了解了WAB和尺度OSGiBundle和和尺度WAR的区分。让我们再深切一下,看看GlassFish是怎样完成OSGiWEB使用程序标准的。
夹杂使用程序Bundle(HybridApplicationBundle)

从GlassFish的角度看,WAB又是夹杂使用程序Bundle的一品种型。夹杂使用程序Bundle既是一个尺度OSGiBundle,又是一个JavaEE模块。在运转时,它既有一个OSGiBundle高低文,又有一个JavaEE高低文。今朝,GlassFish撑持两品种型的夹杂使用程序Bundle,Web使用程序Bundle和EJB使用程序Bundle。关于EJB使用程序Bundle,我将放在Part3中。
当一个夹杂使用程序Bundle被部署到GlassFishOSGi运转时,GlassFish可以察看到它的性命周期,利用熟知的“Extender形式“,将Bundle中的一些部分部署或Undeploy到JavaEE容器中。夹杂使用程序Bundle的性命周期以下所示,

<br>
:夹杂使用程序Bundle的性命周期
摘自:“OSGiApplicationDevelopmentusingGlassFishServer“
假如你细心看一下和,实质上两幅图是一样的,并没有在OSGi性命周期的基础形态上增添4个部署和Undeploy相干的形态,可是,中的4个形态所触及的操纵都反应到了中。
GlassFishOSGiWeb容器的完成

GlassFishOSGiWeb容器完成了OSGiWeb使用程序标准。经由过程部署WAB,我们可以明晰地舆解GlassFish部署OSGiWeb使用程序的流程和怎样完成标准的。部署流程分为两个阶段,

[*]和部署尺度OSGiBundle一样,部署WAB到OSGi运转时中。
[*]当WAB的性命周期变成ACTIVE形态大概STARTING形态(由于有一个怠惰的激活战略)时,部署该WAB到JavaEE运转时中。
必要注重的是,1和2是异步的,这与Undeploy历程分歧,Undeploy是同步的,也就是说,一旦该WAB被中断或卸载,将当即从JavaEE运转时中Undeploy该WAB,而且清算响应的资本。
以下,我将利用“asadmindeploy命令”来分析部署的流程。
【阶段1】部署WAB到OSGi运转时

阶段1的部署次要包含两个部分:a.安装WAB到OSGi运转时b.启动该WAB使其处于ACTIVE形态大概STARTING形态。
以下是部署WAB到OSGi运转时的时序图,

<br>
:部署WAB到OSGi运转时的时序图

[*]依据部署的范例,ApplicationLifecycle类猎取响应的AchiveHandler。由于我们正在部署WAB,当实行“asadmindeploy“命令时,我们传送了“—type=osgi”,因而,部署的范例为osgi。猎取到的AchiveHandler是OSGiArchiveHandler。AchiveHandler卖力处置和会见某种特定档案中的资本,这些档案包含了WAR,JAR,RAR和Bundle。AchiveHandler将在构建部署ClassLoader,猎取Sniffer等后续举措中被利用到。
别的,ApplicationLifecycle类是部署的中心类,也是部署命令中心逻辑实行的出口点,从它的地点的地位可以看出它的主要性,它位于GlassFish内核模块。

[*]接上去,ApplicationLifecycle类经由过程SnifferManagerImpl类猎取响应的Sniffer。那末,甚么是Sniffer呢?自从GlassFishv3入手下手,依据部署的哀求,Sniffer被用来剖析和选择符合的容器来处置使用程序的范例。剖析和选择的历程大概复杂,也大概庞大。比方,经由过程查找WEB-INF/web.xml大概是不是以.war开头来剖析是不是必要WEB容器,也大概经由过程注解(Annotation)扫描来判别是不是必要EJB容器。关于WAB的情况,SnifferManagerImpl前往了OSGiSniffer。进一步地,Sniffer接口有个主要的办法叫“getContainersNames”,关于OSGiSniffer,这个办法前往“osgi”。这个办法将被用来猎取响应的容器。

[*]有了详细的Sniffer以后,ApplicationLifecycle类经由过程ContainerRegistry类的getContainer(StringcontainerType)办法来猎取响应的容器,个中,containerType就是2)中提到的“getContainersNames”的前往值。进一步地,getContainer(StringcontainerType)办法前往了一个EngineInfo对象,这个对象具有特定容器的信息。关于WAB情况,这个特定的容器是OSGiContainer。以下是一个调试的信息,给出了EngineInfo对象中的内容。

[*]
<br>个中,你能够发明container的范例是一个ServiceHandleImp,这是一个HK2相干的类,以下是OSGiContainer的代码,
<build><finalName>${project.artifactId}</finalName><pluginManagement><plugins><plugin><groupId>org.apache.felix</groupId><artifactId>maven-bundle-plugin</artifactId><!--2.2.0andabovehavenewbndwhichhaswabinstruction.2.3.4hasfewimportantbugfixes.--><version>2.3.4</version><extensions>true</extensions><configuration><supportedProjectTypes><supportedProjectType>ejb</supportedProjectType><supportedProjectType>war</supportedProjectType><supportedProjectType>bundle</supportedProjectType><supportedProjectType>jar</supportedProjectType></supportedProjectTypes><instructions><!--ReadallOSGiconfigurationinfofromthisoptionalfile--><_include>-osgi.properties</_include><!--Nopackagesareexportedbydefault.Havinganypatternisdangerous,asthepluginwilladdanypackagefoundindependencychainthatmatchesthepatternaswell.Sincethereisnoeasywaytohaveanincludefilterforjustlocalpackages,wedontexportanythingbydefault.--><Export-Package>!*</Export-Package></instructions></configuration>…</plugin>…</plugins></build><dependencyManagement><dependencies><dependency><groupId>org.osgi</groupId><artifactId>org.osgi.core</artifactId><version>4.2.0</version><scope>provided</scope></dependency>…</dependencies></dependencyManagement><dependencies><!--Addthethefollowingdependenciestoeverymoduletosaveuserfromaddingthemtoeveryone.--><dependency><groupId>org.osgi</groupId><artifactId>org.osgi.core</artifactId></dependency>…</dependencies>7关于HK2的内容,我将在Part7中具体论述。这里复杂地说一下,起首,HK2是一个JSR330的完成。其次,OSGiContainer利用@Service来标注这个类是一个HK2的服务,而且用name属性来便利HK2举行依附注进。别的,利用@Singleton来标注当利用HK2猎取OSGiContainer实例时,利用Singleton的体例。再者,这个类中最为主要的办法是getDeployer,该办法前往了OSGiDeployer,用于后续的OSGi部署。
从以上的界说可以看出,OSGiContainer的实例由HK2卖力创立并非经由过程new出来的,因而,EngineInfo对象中的内容很天然地酿成了ServiceHandleImp。

[*]接上去就是经由过程EngineInfo对象猎取响应的Deployer了,Deployer真正卖力部署{3)中我们已晓得关于WAB情况,EngineInfo将前往OSGiDeployer。

[*]然后,ApplicationLifecycle类托付OSGiDeployer类来安装WAB到OSGi运转时中,OSGiDeployer进而利用BundleContext来安装该WAB。安装乐成后,该WAB的形态将变成INSTALLED。

[*]当安装乐成后,ApplicationLifecycle类入手下手托付OSGiDeployedBundle类来启动该WAB,固然,在启动之前,必要起首判别该Bundle不是一个Fragment,然后再经由过程Bundle.start办法来启动该WAB。

下面提到的Sniffer等观点,在GlassFishWiki中有更加具体地申明。
【阶段2】部署WAB到JavaEE运转时



在论述阶段2之前,必要先回到GlassFishDomain的启动,这部份内容将在Part8中具体地申明。大概你会问,为何要回到GlassFishDomain的启动?
缘故原由在于从阶段1过渡到阶段2,必要做一些需要的事情,比方:在“WAB性命周期”一章中,提到过为了部署WAB到JavaEE运转时,条件前提是守候WAB处于ACTIVE形态或STARTING形态,那末怎样守候?在OSGi开辟中,一个罕见的形式是利用BundleTracker类来跟踪已被安装的Bundle的性命周期变更。一般,翻开BundleTracker的操纵是由OSGiActivator完成的,而OSGiActivator(假如有的话)是启动OSGiBundle开始实行的办法,因而,必需有一个Bundle做如许的BootStrap举措。GlassFishOSGi-JavaEE遵守了这一计划形式,以是,为了弄分明哪些Bundle在完成这些BootStrap举措,我们必需回到GlassFishDomain的启动。
GlassFish安装目次下有个目次叫glassfish4/glassfish/modules/autostart,这里安排了一些Bundle,个中,有两个Bundle与本文亲切相干:1)osgi-javaee-base.jar2)osgi-web-container.jar。
起首,看一下它们的感化,osgi-javaee-base是GlassFishOSGi-JavaEE完成的基类,次要利用了Extender形式来构建全部OSGi-JavaEE的框架,是GlassFishOSGi-JavaEE完成的魂灵。osgi-web-container完成了OSGiWeb标准,也是本文重点要分析的对象。
其次,osgi-javaee-base和osgi-web-container都界说了Activator,当启动GlassFishDomain后,osgi-javaee-base.jar和osgi-web-container.jar被部署到GlassFishOSGi运转时中,且这两个Bundle都被激活处于Active形态,在抵达Active形态之前,各自的Activator都被挪用。让我们来看看它们的Activator都做了甚么。
<olstyle="border-bottom:0px;text-align:left;border-left:0px;padding-bottom:0px;widows:2;text-transform:none;background-color:rgb(255,255,255);list-style-type:decimal;text-indent:0px;margin:10px0px10px10px;padding-left:20px;width:549px;padding-right:0px;display:block;font:14px/21pxArial,sans-serif;white-space:normal;orphans:2;letter-spacing:normal;color:rgb(0,0,0);clear:left;border-top:0px;border-right:0px;word-spacing:0px;padding-top:0px;-webkit-text-size-adjust:auto;-webkit-text-stroke-width:0px">osgi-javaee-base的Activator
osgi-javaee-base的Activator叫“OSGiJavaEEActivator”,它的start办法中中心的逻辑是启动ExtenderManager,和注册并启动JavaEEExtender。ExtenderManager的感化是卖力启动任何已被注册的Extender服务。以下是响应的代码,
<build><finalName>${project.artifactId}</finalName><pluginManagement><plugins><plugin><groupId>org.apache.felix</groupId><artifactId>maven-bundle-plugin</artifactId><!--2.2.0andabovehavenewbndwhichhaswabinstruction.2.3.4hasfewimportantbugfixes.--><version>2.3.4</version><extensions>true</extensions><configuration><supportedProjectTypes><supportedProjectType>ejb</supportedProjectType><supportedProjectType>war</supportedProjectType><supportedProjectType>bundle</supportedProjectType><supportedProjectType>jar</supportedProjectType></supportedProjectTypes><instructions><!--ReadallOSGiconfigurationinfofromthisoptionalfile--><_include>-osgi.properties</_include><!--Nopackagesareexportedbydefault.Havinganypatternisdangerous,asthepluginwilladdanypackagefoundindependencychainthatmatchesthepatternaswell.Sincethereisnoeasywaytohaveanincludefilterforjustlocalpackages,wedontexportanythingbydefault.--><Export-Package>!*</Export-Package></instructions></configuration>…</plugin>…</plugins></build><dependencyManagement><dependencies><dependency><groupId>org.osgi</groupId><artifactId>org.osgi.core</artifactId><version>4.2.0</version><scope>provided</scope></dependency>…</dependencies></dependencyManagement><dependencies><!--Addthethefollowingdependenciestoeverymoduletosaveuserfromaddingthemtoeveryone.--><dependency><groupId>org.osgi</groupId><artifactId>org.osgi.core</artifactId></dependency>…</dependencies>8能够分明地看到,启动的逻辑次要在ExtenderTracker中,让我们看一下
<build><finalName>${project.artifactId}</finalName><pluginManagement><plugins><plugin><groupId>org.apache.felix</groupId><artifactId>maven-bundle-plugin</artifactId><!--2.2.0andabovehavenewbndwhichhaswabinstruction.2.3.4hasfewimportantbugfixes.--><version>2.3.4</version><extensions>true</extensions><configuration><supportedProjectTypes><supportedProjectType>ejb</supportedProjectType><supportedProjectType>war</supportedProjectType><supportedProjectType>bundle</supportedProjectType><supportedProjectType>jar</supportedProjectType></supportedProjectTypes><instructions><!--ReadallOSGiconfigurationinfofromthisoptionalfile--><_include>-osgi.properties</_include><!--Nopackagesareexportedbydefault.Havinganypatternisdangerous,asthepluginwilladdanypackagefoundindependencychainthatmatchesthepatternaswell.Sincethereisnoeasywaytohaveanincludefilterforjustlocalpackages,wedontexportanythingbydefault.--><Export-Package>!*</Export-Package></instructions></configuration>…</plugin>…</plugins></build><dependencyManagement><dependencies><dependency><groupId>org.osgi</groupId><artifactId>org.osgi.core</artifactId><version>4.2.0</version><scope>provided</scope></dependency>…</dependencies></dependencyManagement><dependencies><!--Addthethefollowingdependenciestoeverymoduletosaveuserfromaddingthemtoeveryone.--><dependency><groupId>org.osgi</groupId><artifactId>org.osgi.core</artifactId></dependency>…</dependencies>9ExtenderTracker是一个ServiceTracker,在OSGi开辟中,利用ServiceTracker来跟踪注册的OSGi服务已成了典范的形式。这里,ExtenderTracker跟踪的服务范例是Extender接口。一旦某个Extender被注册,那末ExtenderTracker将挪用addingService办法然后启动这个Extender。
后面提到,除启动ExtenderManager,osgi-javaee-base也注册并启动JavaEEExtender,这个JavaEEExtender十分主要,它的感化就是卖力侦听和部署夹杂使用程序Bundle。看一下它的start办法,
<instructions><_include>-osgi.properties</_include><Export-Package>!*</Export-Package></instructions>0<p>个中,最主要的
但是对于JAVA技术类的学习,我觉得大课堂反而会影响自身独立思考的过程,因为上课的时候,老师讲课的速度很快为了不遗漏要点,通常会仔细的听,

老尸 发表于 2015-1-20 23:47:25

至于JDBC,就不用我多说了,你如果用java编过存取数据库的程序,就应该很熟悉。还有,如果你要用Java编发送电子邮件的程序,你就得看看Javamail 了。

活着的死人 发表于 2015-2-6 08:37:11

你一定会高兴地说,哈哈,原来成为Java高手就这么简单啊!记得Tomjava也曾碰到过一个项目经理,号称Java很简单,只要三个月就可以学会。

小妖女 发表于 2015-2-6 16:32:38

是一种将安全性(Security)列为第一优先考虑的语言

变相怪杰 发表于 2015-2-10 12:04:15

不过,每次的执行编译后的字节码需要消耗一定的时间,这同时也在一定程度上降低了 Java 程序的运行效率。

若天明 发表于 2015-2-16 09:24:36

吧,现在很流行的Structs就是它的一种实现方式,不过Structs用起来实在是很繁,我们只要学习其精髓即可,我们完全可以设计自己的MVC结构。然后你再研究一下软件Refactoring (重构)和极限XP编程,相信你又会上一个台阶。 做完这些,你不如整理一下你的Java代码,把那些经典的程序和常见的应用整理出来,再精心打造一番,提高其重用性和可扩展性。你再找几个志同道合的朋友成立一个工作室吧

飘飘悠悠 发表于 2015-3-5 03:26:26

是一种简化的C++语言 是一种安全的语言,具有阻绝计算机病毒传输的功能

爱飞 发表于 2015-3-6 03:10:31

Java是一个纯的面向对象的程序设计语言,它继承了 C++语言面向对象技术的核心。Java舍弃了C ++语言中容易引起错误的指针(以引用取代)、运算符重载(operator overloading)

精灵巫婆 发表于 2015-3-10 21:58:28

Java 不同于一般的编译执行计算机语言和解释执行计算机语言。它首先将源代码编译成二进制字节码(bytecode),然后依赖各种不同平台上的虚拟机来解释执行字节码。从而实现了“一次编译、到处执行”的跨平台特性。

小女巫 发表于 2015-3-17 11:08:19

吧,现在很流行的Structs就是它的一种实现方式,不过Structs用起来实在是很繁,我们只要学习其精髓即可,我们完全可以设计自己的MVC结构。然后你再研究一下软件Refactoring (重构)和极限XP编程,相信你又会上一个台阶。 做完这些,你不如整理一下你的Java代码,把那些经典的程序和常见的应用整理出来,再精心打造一番,提高其重用性和可扩展性。你再找几个志同道合的朋友成立一个工作室吧

山那边是海 发表于 2015-3-24 08:03:50

如果你学过HTML,那么事情要好办的多,如果没有,那你快去补一补HTML基础吧。其实JSP中的Java语法也不多,它更象一个脚本语言,有点象ASP。
页: [1]
查看完整版本: JAVA网页设计GlassFish OSGi-JavaEE(二):深切了解OSGi WEB使用程序标准和GlassFish OSGi/WEB容 ...