相信很多人在升级eclipse时碰到过这种情况:访问升级页面速度很慢,接下来是更慢的计算依赖项,然后开始安装,而安装时下载插件的速度会慢到无以复加的程度。如果考虑从网络上下载了完整的update site,原本你会以为只需访问本地,那速度应该会快,但事情却并没想像中的好,安装时,eclipse不是去访问本地的这个update site,却在网络上到处下载各种莫名其妙的包,于是,本地update site的软件装起来可能也要花几个小时,有时甚至花了几个小时后发现progress view中的进度条根本就没动过。本人就有过多次这种经历,每次都被这种升级搞得心力交瘁。
现在eclipse的插件太多,每个插件的版本又是各行其是,人为的操作是根本无法处理的,只能用升级管理器。在安装时,明明安装的是 m2eclipse,但从progress view中可以看到,相关的插件来自很多个不同的网站,大家相互依赖,没有人能搞得清楚,只能让升级管理器去找。这个升级管理器是严重依赖于网络的,尤其致命的是,默认情况下,eclipse都是到http://download.eclipse.org/去找插件。你可以添加一个新的升级网站,但却不能改变如下事实:这个新加入的网站中没有的内容,还是要到download.eclipse.org中去下载,新的网站速度是快的,但 download.eclipse.org却依旧慢如蜗牛,于是你还是只能饱受折磨。因特网上download.eclipse.org的镜像并不少见,为什么就不能直接指定最快的镜像网站来升级呢?这不能不说是eclipse升级管理器在设计上的缺陷。也许在美国、欧洲根本就不存在这样的问题吧,而在国内,要想随时从 download.eclipse.org中更新并不轻松。
为了解决这个问题,我现在能想到的解决方案是将eclipse中featues目录下所有feature的feature.xml文件中的升级网站更改为自已设定的网站。至少一点,把对download.eclipse.org的访问重定位到其他网站,像http://download.actuatechina.com/eclipse/等。
用Java实现替换update site的功能,代码如下:
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class UpdateSiteTool{
private static final String DEFAULT_HOME=".";
private static final String DEFAULT_SITE="http://download.eclipse.org/";
private static String getParameter(String des, String[] list) {
int i;
for(i=0;i<list.length && !list[i].equals(des);i++)
;
return i>=list.length-1 ? null : list[i+1];
}
public static void main(String[] args) {
try {
UpdateSiteTool tool=new UpdateSiteTool(
getParameter("-d",args),
getParameter("-o",args),
getParameter("-n",args));
if(!tool.featuresDir.exists() || !tool.featuresDir.isDirectory()) {
System.out.println("Cann't find features directory!");
printUsage();
System.exit(0);
}
if(!args[0].equals("show") && !args[0].equals("change")){
printUsage();
System.exit(0);
}
tool.setStatus(args[0]);
tool.processUpdateSites();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (TransformerConfigurationException e) {
e.printStackTrace();
} catch (TransformerFactoryConfigurationError e) {
e.printStackTrace();
}
}
private static void printUsage() {
System.out.println("Usage: java UpdateSiteTool [show | change] -d eclipse_home "
+"-o original_update_site -n new_update_site");
}
private Transformer transformer;
private DocumentBuilder builder;
private String eclipseHome;
private String originalUpdateSite;
private String newUpdateSite;
private String status; //命令状态,show或change
private File featuresDir;
public UpdateSiteTool(String eclipseHome, String originalUpdateSite, String newUpdateSite)
throws ParserConfigurationException, TransformerConfigurationException, TransformerFactoryConfigurationError {
builder=DocumentBuilderFactory.newInstance().newDocumentBuilder();
transformer=TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT,"yes");
this.eclipseHome= eclipseHome==null ? DEFAULT_HOME : eclipseHome;
this.originalUpdateSite= originalUpdateSite==null ? DEFAULT_SITE : originalUpdateSite;
this.newUpdateSite= newUpdateSite==null ? DEFAULT_SITE : newUpdateSite;
String features = this.eclipseHome.endsWith(File.separator) ?
this.eclipseHome+"features" : this.eclipseHome+File.separator+"features";
featuresDir=new File(features);
}
private void changeUpdateSites( Node item) {
Element e=(Element)item;
String siteUrl=e.getAttribute("url");
System.out.println("origin site="+siteUrl);
siteUrl=siteUrl.replaceFirst(this.originalUpdateSite, this.newUpdateSite);
System.out.println("new site="+siteUrl);
e.setAttribute("url", siteUrl);
}
private void printUrlElement(Node item) {
Element e=(Element)item;
System.out.print("tagname="+e.getTagName()+" url="+e.getAttribute("url")+"/n");
}
private void processUpdateSites() {
File[] files=featuresDir.listFiles();
for(File f : files) {
f.setWritable(true);
System.out.println("feature name: "+f.getName());
File featureFile=new File(f,"feature.xml");
try {
Document doc=builder.parse(featureFile);
Element root=doc.getDocumentElement();
NodeList urlNodes=root.getElementsByTagName("url");
if(urlNodes.getLength()==0)
continue;
NodeList nodes=urlNodes.item(0).getChildNodes();
for(int i=0;i<nodes.getLength();i++)
if(nodes.item(i) instanceof Element)
if(this.status.equals("show"))
printUrlElement(nodes.item(i));
else
changeUpdateSites(nodes.item(i));
System.out.println();
if(this.status.equals("change"))
transformer.transform(new DOMSource(doc), new StreamResult(new FileOutputStream(featureFile)));
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (TransformerException e) {
e.printStackTrace();
}
f.setWritable(false);
}
}
public void setStatus(String status) {
this.status = status;
}
}
程序运行格式如下:
show表示查看当前features的update site列表
change表示更改update site
-d选项用于指定eclipse安装目录
-o选项用于指定原update site网址
-n选项用于指定新update site网址
下面的命令可以将所有feature.xml中的http://download.eclipse.org/替换成http://download.actuatechina.com/eclipse/
java UpdateSiteTool change -d d://eclipse-jee -n http://download.actuatechina.com/eclipse/
下面的命令将http://download.actuatechina.com/eclipse/替换成http://ftp.kaist.ac.kr/eclipse/
java UpdateSiteTool change -d d://eclipse-jee -o http://download.actuatechina.com/eclipse/ -n http://ftp.kaist.ac.kr/eclipse/
eclipse的镜像可以在下面列表上得到提示,但不是所有网址都可以这么去改,有的网址没有update site。
在替换以后,重启eclipse,注意要带–clean参数,这时用新的网站去升级时,可以在progress view中注意到,各个插件的默认下载网址已经改成新的网址了。
不能指望这样改了以后就解决所有问题,不少插件还是要去国外的网址下载。同时,eclipse自带的机制没有考虑到用户会这么改,用的时候会出现比较古怪的网址。那些以download.eclipse.org开头的升级网址是无法删除的,即使强制删除了,更新一用,马上就会回来,就不要去管它们了。
自己个人使用经验来看,比没改之前升级要好一些,推荐大家使用。