愤怒的大鸟 发表于 2015-1-18 11:14:47

JAVA网站制作之发明 Eclipse 中未剖析的插件依附性

java也能做一些底层语言开发做的事情(难度很高,不是java顶尖高手是做不来的),  试图定位没法剖析的插件依附性是件严重而又耗时的事变。激活每一个插件都要依附于良多其他插件,这些插件又会依附于其他更多插件。假如Eclipse没法加载这个长长的链条中的某个插件,那末手工查找呈现成绩的究竟是哪一个插件大概会比原企图所消费的工夫和精神都要多。假如您但愿有一种办法能够主动完成这类插件依附性的检测,就请浏览本文。

  碰着的成绩

  假定我们但愿在Eclipse中利用一个特定的插件,并已实行了一切必需的操纵,将其包括到插件的manifest文件中,并将其声明为一个依附文件。可是体系并没有加载这个插件,如许我们就会被困在这里了,软件开辟就没法持续停顿下往了。

  听起来十分熟习吗?假如是如许,那末您大概早已消费了良多工夫和勉力来检察良多plugin.xml文件,从而查明Eclipse大概没有加载哪一个特定的插件。还大概已实验利用了EclipsePDE项目供应的Plug-inDependencies视图,此时您会发明这个视图的独一事情不外是显现已乐成加载的插件罢了。不幸的是,有成绩的插件极可能其实不属于乐成加载的插件。

  要断定Eclipse没有找到或加载哪一个特定的插件,我们应当做些甚么呢?我们不必手工遍历每一个plugin.xml文件,而是思索主动完成这类搜刮功效。要主动举行搜刮,我们必要懂得Eclipse是怎样保留本人的插件的,和怎样发明到保留在磁盘上的其他插件的链接。基于这些常识,我们大概会但愿编写本人的代码来创立一个插件依附性遍过程序,大概利用在本文中给出的这个通用的DependencyWalker插件。本文的“下载”一节给出了这个例子的源代码。

  入手下手:了解插件依附性和Eclipse的插件链

  插件依附性

  Eclipse插件是供应了其他插件可使用的功效的软件模块。假如插件A必要插件B才干一般事情,那末我们就说A依附于B。这类依附性还意味着,除非插件B已乐成加载了,不然插件A就不克不及一般事情。偶然候,插件B大概还会依附于插件C、D、E,使人更不爽的是,这些插件每一个都大概会依附于其他插件。这类依附链很简单构成数百个插件互相链接在一同。毫无疑问,假如这个链条中的任何一个插件不克不及乐成加载,那末依附它的插件便可能会呈现成绩。

  插件manifest文件plugin.xml形貌了每一个插件。这个XML文件中有一节声了然关于其他插件的依附性或需求。在清单1中,plugin.xml文件中利用黑体暗示的一节就声了然这类依附性。

  清单1.plugin.xml文件
<?xmlversion="1.0"encoding="UTF-8"?><?eclipseversion="3.0"?><pluginid="org.eclipse.draw2d"name="Draw2d"version="3.0.0"provider-name="Eclipse.org"><runtime><libraryname="draw2d.jar"><exportname="*"/><packagesprefixes="org.eclipse.draw2d"/></library></runtime><requires><importplugin="org.eclipse.swt"export="true"/><importplugin="org.eclipse.core.runtime"/></requires></plugin>
  注重嵌进在<requires></requires>节中的<importplugin="pluginid"/>声明。清单1的例子申明这个插件IDorg.eclipse.draw2d依附于ID为org.eclipse.swt和org.eclipse.core.runtime的插件。

  插件链

  当我们在Eclipse中利用Java?手艺平台来开辟软件时,体系实践上依据所选择的方针平台对源代码举行编译。能够在Window>Preferences>Plug-inDevelopment>TargetPlatform中指定方针平台的地位。这个方针平台在<targetPlatform>eclipse中有本人的一个Eclipse正本。要为代码剖析这些依附性,请从两个中央查找是不是存在所必要的插件:

[*]<targetPlatform>eclipseplugins文件夹中的Eclipse插件
[*]<targetPlatform>eclipselinks文件夹中.link文件所指向的链接插件
  程序员一般会将第二个中央称为links文件夹。这个links文件夹中包括0个或多个文件,文件名一般都是以“.link”扩大名开头。这些文件中包括了一些链接信息,可使用这些信息定位在磁盘上哪些中央能够找到链接插件。

  每一个.link文件都有一个关头字-值对,其格局为path=location。(比方,links文件夹C:eclipselinks中便可能会有良多.link文件,个中一个文件的名字大概为com.ibm.indiver.dependencywalker.link。这个文件中独一的一行大概相似于path=c:myPluginsdependencyWalker)。这个.link文件会将Eclipse引诱到指定的地位,并在eclipseplugins文件夹中寻觅更多的可用插件。
  创立本人的Eclipse插件依附性遍过程序

  编写一个依附性遍过程序基础上分为两个步骤:起首排列出一切插件,其次排列出用户所选择的插件的依附性。

  第一个步骤要卖力定位Eclipse体系中呈现的每一个插件,并在一个复杂的用户界面(UI)――比方表――中为终端用户供应一切插件的清单。这个UI还应当为用户供应一些办法来选择但愿剖析其依附性的插件。

  第二个步骤则要对用户选择的插件的plugin.xml文件举行剖析,并查找这个plugin.xml文件中嵌进的<importplugin="pluginid"/>声明。这类勉力明显必要对每一个插件的manifest文件举行递回搜刮,从而查明依附插件的全部链条。关于形貌这个插件大概依附于其他插件的父-兄-子干系,树状视图是最符合的一种UI。我们还应当能够直不雅地看出某个Eclipse插件注册项是不是真正加载了一个物理存在的插件。

  步骤1:排列Eclipse体系中的一切插件

  在把握了以下信息以后,就能够编写一些代码来排列磁盘上物理存在的一切插件了:


[*]插件次要在<targetPlatform>eclipseplugins文件夹中。
[*]在其他几个<someLinkedPath>eclipseplugins文件夹中也大概会找到插件。
[*]从<targetPlatform>eclipselinks文件夹中的.link文件中能够取得到每一个<someLinkedPath>的路径。
  上面是排列Eclipse体系中一切插件的具体步骤:


[*]找到方针平台的地位。
[*]筹办links文件夹的路径。links文件夹在eclipse文件夹中。
[*]取得eclipselinks文件夹中文件的清单。请参考源代码中的Utilities.getLinkedPaths()函数。
[*]检察每一个.link文件,猎取链接Eclipse插件的路径。
[*]筹办一个一切插件根文件夹的清单(即,<targetPlatform>eclipseplugins文件夹和一切大概的<someLinkedPath>eclipseplugins文件夹)。
[*]关于每一个根文件夹,进进每一个插件目次中,并猎取plugin.xml文件的路径。
[*]对plugin.xml文件举行剖析,取得插件ID和插件版本,并将这些信息保留到一个数据布局中。
[*]回到步骤6,持续处置下一个插件目次。
<P>  清单2.筹办在Eclipse体系下物理存在的一切插件的清单
/****@returnreturnsaVectorcontainingPluginDataobjects.*EachPluginDataobjectrepresentsaPluginfoundunderanyofthefollowing*plugindirectories*a.thetargetPlatformLocationeclipsepluginsdirectory,*b.otherplugindirectoriesasspecifiedby*.linkfilesunder*targetPlatformeclipselinksdirectory**/publicstaticVectorgetPluginsInTargetPlatform(){/**//step1:Getpathoftargetplatform.//step2:Preparepathoflinksfolder.//step3:Getlistoffilesinlinksfolder.//step4:ParseeachlinkfileandgetthepathoflinkedEclipsefolder.//step5:Preparealistofallpluginrootfolders//(EclipsepluginsandlinkedEclipseplugins).//step6:6a.Foreachpluginrootfolder,//6b.gotoeachplugindirectoryandgetpathofplugin.xml.//step7:Parsetheplugin.xmlfiletogetpluginid,pluginversion,//andstoreinvectors,lists,etc.//step8:Gobacktostep6tocontinuewithnextplugindirectory.**///step1:Getpathoftargetplatform.//FallbacktoEclipseinstalllocationiftargetplatforminnotset.URLplatFormURL=Platform.getInstallLocation().getURL();Locationlocation=Platform.getInstallLocation();IPatheclipsePath=null;//Getpathoftargetplatformagainstwhichtheusersofthistool//willcompiletheircode.IPathtargetPlatFormLocation=newPath(getTargetPlatformPath(true));if(_useTargetPlatform==false)eclipsePath=newPath(platFormURL.getPath());elseeclipsePath=targetPlatFormLocation;showMessage("Consideringtargetplatformtobe:"+eclipsePath.toString());//step2:Preparepathoflinksfolder.//step3:Getlistoffilesinlinksfolder.//step4:ParseeachlinkfileandgetthepathoflinkedEclipsefolder.IPathlinksPath=newPath(eclipsePath.toString()).append("/links");StringlinkedPaths[]=getLinkedPaths(linksPath.toString());intlinkedPathLength=0;if(null!=linkedPaths){linkedPathLength=linkedPaths.length;}//step5:Preparealistofallpluginrootfolders//(EclipsepluginsandlinkedEclipseplugins).IPatheclipsePluginRootFolders[]=newIPath;eclipsePluginRootFolders=newPath(eclipsePath.toString()).append("/plugins");if(null!=linkedPaths){for(inti=0;i<linkedPaths.length;i++){eclipsePluginRootFolders=newPath(linkedPaths).append("/eclipse/plugins");}}//step6:6a.Foreachpluginrootfolder,//6b.gotoeachplugindirectoryandgetpathofplugin.xml.//step7:Parsetheplugin.xmlfiletogetpluginid,pluginversion,//andstoreinvectors,lists,etc.VectorvectorsInThisVector=newVector();for(inti=0;i<eclipsePluginRootFolders.length;i++){System.out.println("
========pluginIDsandVersionsin"+eclipsePluginRootFolders+"========");VectorpluginDataObjs=getPluginDataForAllPlugins(eclipsePluginRootFolders.toString());vectorsInThisVector.add(pluginDataObjs);System.out.println(pluginDataObjs);System.out.println("
===========|||===end===|||===========");}VectorpluginData=newVector();IteratorouterIterator=vectorsInThisVector.iterator();while(outerIterator.hasNext()){VectorpluginDataObjs=(Vector)outerIterator.next();IteratorinnerIterator=pluginDataObjs.iterator();while(innerIterator.hasNext()){PluginDatapd=(PluginData)innerIterator.next();StringpluginIdKey=pd.getPluginID();StringversionValue=pd.getPluginVersion();StringpluginPath=pd.getPluginLocation();pluginData.add(pd);}}intbreakpoint=0;returnpluginData;}
  在把握了一切的插件以后,我们就能够显现插件的ID、版本、地位和更多信息了,这些能够显现在一个StandardWidgetToolkit(SWT)表中,从而使这些信息加倍直不雅。我们也能够编写一些代码依据插件ID列举行排序,就像是我们的样例代码一样。还应当在一列中申明找到了几个插件。了局应当以下所示:

  .Target-Platform视图中的一切插件


  步骤2:对plugin.xml文件举行递回搜刮,从而遍历全部依附链
  当用户选择但愿剖析依附链的插件以后,我们就必要对用户所选择的插件的plugin.xml文件举行剖析,从而检察它的依附性。每一个依附性城市招致反省别的一个plugin.xml文件,后者又有本人的依附性。从用户选择的插件入手下手,这个依附链能够敏捷招致有良多个plugin.xml文件必要举行剖析。我们能够编写一个递回函数来遍历这些依附性,它能够查找某个插件的最新版本(针对在不异的体系中有反复插件的情形)和它的一切依附性。

  编写这类递回函数必要实行的步骤以下所示,清单3给出了这个函数的源代码。递回函数偶然对资本的损耗量很年夜,并且在用户得到耐烦之前大概还没有前往了局。别的一种选择是编写一个函数,只猎取用户选择的插件的间接依附性清单。后一种办法请参看样例代码中的loadImmediateDependencies()函数。


[*]取得用户选择的插件的路径。
[*]反省这个地位上是不是存在plugin.xml或fragment.xml文件。
[*]对plugin.xml或fragment.xml文件举行剖析,从而取得这个插件所必要的一切插件的清单。
[*]关于这个清单中的每一个插件ID,寻觅对应的插件。
[*]假如多个插件具有不异的ID,就只向用户呈报一次,并主动断定利用版本较新的插件。怎样编程对插件版本举行对照并寻觅一个版本较新的插件,请参看。

[*]将(步骤4或4a中找到的)插件增加到一个树视图中,并递回地挪用不异的函数,再次从步骤1入手下手从头实行。不外此次用户不必再选择插件了;步骤4或4a对应的代码会卖力选择插件。
<P>  清单3.recursivePluginDependencyWalker()函数
privateVectoralreadyNotified=newVector();privatebooleanfirstCall=true;privateTreeParentroot=null;privatevoidrecursivePluginDependencyWalker(PluginDatapdObject,TreeParentparentNode){try{Stringpath=pdObject.getPluginLocation();PluginParserpp=null;FilepluginDotXmlFile=newFile(path+"/plugin.xml");if(pluginDotXmlFile.exists()){pp=newPluginParser(pluginDotXmlFile);}else{FilefragmentDotXmlFile=newFile(path+"/fragment.xml");if(fragmentDotXmlFile.exists()){pp=newPluginParser(fragmentDotXmlFile);}else{return;//noplugin.xmlorfragment.xmlfound}}StringdisplayName=pdObject.getDisplayName();System.out.println("
Plugin["+displayName+"]requires"+"
");Stringrequires[]=pp.getDependencyList();if(0!=requires.length){for(inti=0;i<requires.length;i++){System.out.println("        "+requires);PluginDatapd[]=getPluginDataObjectsFromPluginID(requires);PluginDatanextPlugin=null;switch(pd.length){case0://great,weknowthereis//somethingmissingnextPlugin=null;break;case1://bestcase,everythingwillbesmoothnextPlugin=pd;break;default://worstcase,theremustbemore//than1pluginwiththesameid//atdifferentlocations.StringmsgLine1="Plugin"+displayName+"requires"+requires+"
";StringmsgLine2="Duplicateplug-insfoundforID:""+requires+"""+"
Continuingwithhigherversion...";//itisbadtogiverepeated//reminders,//soremindonlyonceperpluginid.if(!alreadyNotified.contains(newString(requires))){MessageDialog.openInformation(null,"DependencyWalker",msgLine1+msgLine2);alreadyNotified.add(newString(requires));}//alwaystakethebetter//versionanywaynextPlugin=getBetterVersionPlugin(pd);break;}//endofswitchif(null!=nextPlugin){TreeParentnextinLine=newTreeParent(nextPlugin.getDisplayName(),nextPlugin.isPluginLoadedInRegistry());parentNode.addChild(nextinLine);recursivePluginDependencyWalker(nextPlugin,nextinLine);}else{TreeParentnextinLine=newTreeParent(requires+"",false);parentNode.addChild(nextinLine);//obviouslywecantrecurse//intoamissingplugin...}}//endoffor}else{System.out.println("        NOTHING:Nofurtherdependency
");//nofurtherdependency}}catch(Exceptione){e.printStackTrace();}}
  偶然候,我们会碰着在分歧地位存在具有不异ID的插件的情形。比方,ID为org.eclipse.xsd的插件大概会在<targetPlatform>eclipseplugins文件夹和<someLinkedPath>eclipseplugins文件夹中同时呈现。

<P>  在这类情形中,必需要断定从这两个或更多个磁盘正本当选用哪一个插件。明显,我们所感乐趣的应当是最新的插件,也就是说,版本较新的插件。我们能够使用现有的一些函数来对Eclipse插件的版本举行对照,大概能够基于清单4所示的样例代码编写一个复杂的函数来对插件版本举行对照。

  清单4.对照插件版本
privatePluginDatagetBetterVersionPlugin(PluginDatapdo[]){PluginData_pdObjs[]=pdo;intlen=pdo.length;if(len==0)returnnull;Arrays.sort(_pdObjs,newComparator(){/**Comparesitstwoargumentsfororder.*Returnsanegativeinteger,zero,orapositiveinteger*asthefirstargumentislessthan,equalto,orgreaterthan*thesecond.**/publicintcompare(ObjectleftObj,ObjectriteObj){StringleftPID=((PluginData)leftObj).getPluginVersion().replace(.,:);StringritePID=((PluginData)riteObj).getPluginVersion().replace(.,:);StringleftID[]=leftPID.split(":");StringriteID[]=ritePID.split(":");intmaxlen=leftID.length>riteID.length?leftID.length:riteID.length;for(inti=0;i<maxlen;i++){intleft=0;intrite=0;try{left=newInteger(leftID).intValue();}catch(NullPointerExceptione){left=0;}try{rite=newInteger(riteID).intValue();}catch(NullPointerExceptione){rite=0;}if(left==rite){continue;}else{intbigger=left>rite?left:rite;if(bigger==left)return1;if(bigger==rite)return-1;}}return0;}publicbooleanequals(Objectarg0){returnfalse;}});return_pdObjs;}
  在代码遍历完全个链接依附性链以后,我们就能够利用一个树视图来直不雅地将其暗示出来。还应当直不雅地指出(请参看下图中的红圈)是哪个插件招致了加载失利。

  这个搜刮的了局应当相似于下图所示:

  .DependencyWalkerTreeView


  停止语

  假如我们但愿定位一些没法剖析的插件依附性(短少插件或Eclipse因为某些缘故原由未能加载它们),起首可使用EclipsePDEPlug-inDependencies视图来显现插件的依附性。假如Plug-inDependencies视图没有显现我们的插件,便可能但愿利用本文中先容这个工具对一切链接插件文件夹举行主动化搜刮。假如您只对某个详细的插件感乐趣,也能够对这段代码举行修正来满意您的请求。

  能够从上面的“下载”一节取得这个工具的源代码。要扫瞄源代码,请睁开源代码包,并将这个插件作为一个Eclipse项目翻开。要利用这个工具,请将这个插件解压到eclipseplugins文件夹中,并实行以下操纵:


[*]在Eclipse中,切换到Window>ShowView>Others>DependencyWalkerCategory中,并选择AllPluginsinTarget-Platform视图。
[*]这个视图会显现在指定方针平台中呈现的一切插件。选择一个插件并双击它。
[*]DependencyWalkerTreeView会显现您所选择的插件的一切依附性。完成以后,请封闭这个视图。

你通过从书的数量和开发周期及运行速度来证明:net和ruby要比java简单。

莫相离 发表于 2015-1-18 23:21:24

是一种为 Internet发展的计算机语言

老尸 发表于 2015-1-24 05:20:12

Pet Store.(宠物店)是SUN公司为了演示其J2EE编程规范而推出的开放源码的程序,应该很具有权威性,想学J2EE和EJB的朋友不要 错过了。

简单生活 发表于 2015-1-31 20:57:23

是一种使用者不需花费很多时间学习的语言

愤怒的大鸟 发表于 2015-2-6 22:31:47

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

小女巫 发表于 2015-2-7 15:39:54

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

只想知道 发表于 2015-2-22 11:38:31

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

若天明 发表于 2015-3-1 18:10:29

你可以去承接一些项目做了,一开始可能有些困难,可是你有技术积累,又考虑周全,接下项目来可以迅速作完,相信大家以后都会来找你的,所以Money就哗啦啦的。。。。。。

admin 发表于 2015-3-7 08:12:45

接着就是EJB了,EJB就是Enterprise JavaBean, 看名字好象它是Javabean,可是它和Javabean还是有区别的。它是一个体系结构,你可以搭建更安全、更稳定的企业应用。它的大量代码已由中间件(也就是我们常听到的 Weblogic,Websphere这些J2EE服务器)完成了,所以我们要做的程序代码量很少,大部分工作都在设计和配置中间件上。

飘灵儿 发表于 2015-3-10 12:25:48

另外编写和运行Java程序需要JDK(包括JRE),在sun的官方网站上有下载,thinking in java第三版用的JDK版本是1.4,现在流行的版本1.5(sun称作J2SE 5.0,汗),不过听说Bruce的TIJ第四版国外已经出来了,是专门为J2SE 5.0而写的。

活着的死人 发表于 2015-3-11 12:44:31

一直感觉JAVA很大,很杂,找不到学习方向,前两天在网上找到了这篇文章,感觉不错,给没有方向的我指了一个方向,先不管对不对,做下来再说。

金色的骷髅 发表于 2015-3-20 06:45:52

另外编写和运行Java程序需要JDK(包括JRE),在sun的官方网站上有下载,thinking in java第三版用的JDK版本是1.4,现在流行的版本1.5(sun称作J2SE 5.0,汗),不过听说Bruce的TIJ第四版国外已经出来了,是专门为J2SE 5.0而写的。
页: [1]
查看完整版本: JAVA网站制作之发明 Eclipse 中未剖析的插件依附性