<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>ZhongZiChang&#039;s Dao</title>
	<atom:link href="http://www.zhongzichang.com/feed" rel="self" type="application/rss+xml" />
	<link>http://www.zhongzichang.com</link>
	<description></description>
	<lastBuildDate>Wed, 07 Mar 2012 11:07:45 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>在GWT中使用异步调用链</title>
		<link>http://www.zhongzichang.com/archives/355</link>
		<comments>http://www.zhongzichang.com/archives/355#comments</comments>
		<pubDate>Wed, 07 Mar 2012 11:07:45 +0000</pubDate>
		<dc:creator>zhongzichang</dc:creator>
				<category><![CDATA[开发工具]]></category>
		<category><![CDATA[gwt]]></category>
		<category><![CDATA[开发]]></category>

		<guid isPermaLink="false">http://www.zhongzichang.com/?p=355</guid>
		<description><![CDATA[为了让应用能运行在iOS/Android/WP等各种手机平台上，我试了一下GWT。在浏览器的初始化过程中发现的两个问题，分别是如何处理异步调用的依赖和MVP的页面区块嵌套。 这里先说异步调用链，MVP的如何实现页面区块的嵌套放在下一次。 客户端通常需要调用多个远程接口来装载页面需要的数据。如果某写接口调用失败，则相应的数据显示不了，并且一些RPC之间对数据有依赖性。例如一个用户登录后，转到应用的首页，首页需要显示当前登录的用户信息和他的朋友列表。那么在 onModuleLoad 的过程中需要执行两个调用。分别是 accountService.getCurrentUser() 和 friendService.listFriends()。这个时候如何第一个调用失败那么程序就不应该执行第二个调用，而是直接报告数据读取出错，否则页面上某些数据显示不出来，比较奇怪。这个时候就需要异步调用链。为此我写了一个接口和一个类来实现链式调用。 AsyncCall.java &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;- /** * 异步调用接口，实现这个接口的对象可以添加到 AsyncCallChain 中，支持逐个调用。 * @author zzc * */ public interface AsyncCall { void call(AsyncCallChain chain) throws Exception; } &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;// AsyncCallChain.java &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;- import java.util.ArrayList; /** * 异步调用链 * @author &#8230; <a href="http://www.zhongzichang.com/archives/355">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>为了让应用能运行在iOS/Android/WP等各种手机平台上，我试了一下GWT。在浏览器的初始化过程中发现的两个问题，分别是如何处理异步调用的依赖和MVP的页面区块嵌套。</p>
<p>这里先说异步调用链，MVP的如何实现页面区块的嵌套放在下一次。</p>
<p>客户端通常需要调用多个远程接口来装载页面需要的数据。如果某写接口调用失败，则相应的数据显示不了，并且一些RPC之间对数据有依赖性。例如一个用户登录后，转到应用的首页，首页需要显示当前登录的用户信息和他的朋友列表。那么在 onModuleLoad 的过程中需要执行两个调用。分别是 accountService.getCurrentUser() 和 friendService.listFriends()。这个时候如何第一个调用失败那么程序就不应该执行第二个调用，而是直接报告数据读取出错，否则页面上某些数据显示不出来，比较奇怪。这个时候就需要异步调用链。为此我写了一个接口和一个类来实现链式调用。</p>
<p>AsyncCall.java &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<blockquote><p><code>/**<br />
* 异步调用接口，实现这个接口的对象可以添加到 AsyncCallChain 中，支持逐个调用。<br />
* @author zzc<br />
*<br />
*/<br />
public interface AsyncCall {<br />
    void call(AsyncCallChain chain) throws Exception;<br />
}</code></p></blockquote>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;//</p>
<p>AsyncCallChain.java &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<blockquote><p><code>import java.util.ArrayList;</p>
<p>/**<br />
* 异步调用链<br />
* @author zzc<br />
*<br />
*/<br />
public class AsyncCallChain {<br />
    public static enum Status {READY, AFOOT, END}; // 准备好，进行中，结束了<br />
    private ArrayList&lt;AsyncCall&gt; calls = new ArrayList&lt;AsyncCall&gt;();<br />
    private int index = 0;<br />
    private Status status = Status.READY;</p>
<p>    public void go() throws Exception {<br />
        status = Status.AFOOT;<br />
        doNext();<br />
    }</p>
<p>    public void doNext() throws Exception {<br />
        if(calls.size() &gt; index) {<br />
            index++;<br />
            calls.get(index-1).call(this);<br />
        } else {<br />
            status = Status.END;<br />
        }<br />
    }</p>
<p>    public void addCall(AsyncCall call) {<br />
        calls.add(call);<br />
    }</p>
<p>    public Status getStatus(){<br />
        return status;<br />
    }<br />
}</code></p></blockquote>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; //</p>
<p>怎么使用上面的接口和类？</p>
<p>首先我们先编写两个类 GetCurrentUserAsyncCall 和 ListFriendsAsyncCall，都实现 AsyncCall 接口。这里给出 GetCurrentUserAsyncCall 的部分代码。</p>
<blockquote><p><code>public class GetCurrentUserAsyncCall implements AsyncCall {<br />
    @Override<br />
    public void call(final AsyncCallChain chain) throws Exception {<br />
        service.getCurrentUser(new AsyncCallback&lt;User&gt;(){<br />
            @Override<br />
            public void onFailure(Throwable caught) {<br />
                // 调用失败，应该显示数据读取错误，并且终止进一步的操作<br />
                ...<br />
            }</p>
<p>            @Override<br />
            public void onSuccess(User user) {<br />
                // 调用成功，执行下一步<br />
                chain.doNext();<br />
        }});<br />
    }</p>
<p>}</code></p></blockquote>
<p>然后在 onLoadModule 的过程中创建链，并逐个执行。</p>
<blockquote><p><code>AsyncCallChain chain = new AsyncCallChain(); // 创建链式调用<br />
chain.addCall(new GetCurrentUserAsyncCall(clientFactory)); // 获取当前用户信息<br />
chain.addCall(new ListFriendsAsyncCall(clientFactory)); // 获取朋友列表<br />
chain.addCall(new HistoryHandleAsyncCall(clientFactory)); // 历史处理（MVP用来激活指定的 Activity）<br />
chain.go(); // 开始执行</code></p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.zhongzichang.com/archives/355/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Eclipse平台插件开发者指南之一 Eclipse是什么</title>
		<link>http://www.zhongzichang.com/archives/350</link>
		<comments>http://www.zhongzichang.com/archives/350#comments</comments>
		<pubDate>Wed, 14 Sep 2011 05:11:18 +0000</pubDate>
		<dc:creator>zhongzichang</dc:creator>
				<category><![CDATA[Eclipse]]></category>

		<guid isPermaLink="false">http://www.zhongzichang.com/archives/350</guid>
		<description><![CDATA[Eclipse 是一个平台。目前它已经被设计成用于建造集成的Web和桌面应用的工具。在设计时，平台并没有给最终用户提供很多的功能。这个平台的价值在于，它能让用户以插件的方式快速开发可集成的功能部件。 Eclipse提供一套常用的UI模型，支持多种操作系统。按照Eclipse提供的可移植API编写的插件，不需要做任何修改，就可以在所有支持的操作系统上运行。 Eclipse 的核心，一个能够动态发现，装载，和运行插件的架构。平台负责发现和运行代码。UI提供一个标准的引导用户使用平台的模型。插件则专注于小数量的任务上。是哪种类型的任务呢？定义，测试，动画，发布，编译，调试，绘图&#8230;一切只要你想得到。 开放的架构 Eclipse 提供一个开放的架构，其他的开发团队可以在他们专长的领域里面给这个平台开发插件。如，仓库专家建造后端，使用方面(UE)的专家建造前端。可以增加重要的新功能部件和层次，而不会与其他的工具冲突。 从用户的角度来看，Eclipse 平台使用一个共同的工作台的模型。你可以将开发的工具通过它预先定义的钩子（extension points）插入到工作台中。 这个平台是由插件以层次的方式建成，每一个插件定义了更低层次的插件的扩展点的扩展，也可为更高层次的插件自定义扩展点。这种扩展模式可以让开发者给基础工具平台增加不同的功能。每一个工具生产出来的人工品，比如文件和其他的数据，由一个共同的平台资源模型来协调。 插件的开发者可以从这个架构中获得很多。这个平台管理多种不同的运行时环境，例如不同的操作系统或者工作组服务器环境。插件开发者能够专心完成他们的任务，不用担心有关集成的问题。 平台架构 Eclipse平台本身就是一个子系统，在由一个或者多个插件中实现。这个子系统在一个小型的运行时引擎的上面建造。下图做一个简单的描绘。拼凑成这个子系统的插件为给平台增加行为， 而定义了多个扩展点。下表描述这个平台的主要运行时组件，由一个或者多个插件实现。平台运行时&#160;&#160; &#160;定义了扩展点与插件模型。动态发现插件和在一个平台注册表中维护插件及其扩展点的信息。当需要响应用户对平台的操作时，插件被启动。运行时使用OSGi框架实现。资源管理（workspace）&#160;&#160; &#160;为资源的创建和管理，定义的API。这些资源包括项目、文件和目录，都是由工具生成并且保存在文件系统里。工作台UI&#160;&#160; &#160;实现用户纵览平台的座舱。定义了扩展点，为增加UI组件，比如 views 或者 菜单 actions。提供附加的工具（JFace和SWT）来建造用户界面。UI服务是结构化的，因此UI插件的子集能够被用于建造RCA，独立与资源管理和workspace模型。以IDE为中心的插件为纵览和操纵资源，定义了另外的功能。帮助系统&#160;&#160; &#160;像书籍一般，给插件来定义扩展点，能够提供帮助或者其他的文档。团队支持&#160;&#160; &#160;为管理和版本化资源，定义了一个团队编程模型。调试支持&#160;&#160; &#160;定义了一个语言独立的调试模型和UI类，为的是建造调试器和运行器。其他工具&#160;&#160; &#160;其他的插件，比如支持搜索和资源比较，使用XML配置文件执行建造，从服务器那里动态升级平台。 盒子之外 离开了Web，基础平台就是一个IDE，没有什么特别的。 它是一个检查平台的最终功能的插件。这就是为什么Eclipse SDK和额外的插件一起装运，来增加SDK的功能。 你的插件可以提供这样的支持，编辑和操作额外的资源类型，例如Java文件、C程序、Word文档、HTML页面和JSP文件。 挑战 我们要求达到一个这样的集成水准，魔法般将独立的开发工具揉合到一个设计套件中。已有的工具可以足够简单的迁移到平台中，不需要强塞硬撬。 平台应该是开放的，用户可以选择工具，并且他们知道供应商在底层平台的开发过程中说了些什么。 它应该足够简单，容易理解，足够强壮，无须额外的粘和剂就支持集成。 提供工具，将平凡常用普通的任务自动化。足够稳定，让业界强壮的工具在其上面建造。非常有用，平台的开发者可以使用它来建造它本身。 上面都是Eclipse的目标。这个手册将帮助你检查Eclipse如何去实现这些想法。]]></description>
			<content:encoded><![CDATA[<p>Eclipse 是一个平台。目前它已经被设计成用于建造集成的Web和桌面应用的工具。在设计时，平台并没有给最终用户提供很多的功能。这个平台的价值在于，它能让用户以插件的方式快速开发可集成的功能部件。</p>
<p>Eclipse提供一套常用的UI模型，支持多种操作系统。按照Eclipse提供的可移植API编写的插件，不需要做任何修改，就可以在所有支持的操作系统上运行。</p>
<p>Eclipse 的核心，一个能够动态发现，装载，和运行插件的架构。平台负责发现和运行代码。UI提供一个标准的引导用户使用平台的模型。插件则专注于小数量的任务上。是哪种类型的任务呢？定义，测试，动画，发布，编译，调试，绘图&#8230;一切只要你想得到。</p>
<p><b><big><big>开放的架构</big></big></b></p>
<p>Eclipse 提供一个开放的架构，其他的开发团队可以在他们专长的领域里面给这个平台开发插件。如，仓库专家建造后端，使用方面(UE)的专家建造前端。可以增加重要的新功能部件和层次，而不会与其他的工具冲突。</p>
<p>从用户的角度来看，Eclipse 平台使用一个共同的工作台的模型。你可以将开发的工具通过它预先定义的钩子（extension points）插入到工作台中。</p>
<p>这个平台是由插件以层次的方式建成，每一个插件定义了更低层次的插件的扩展点的扩展，也可为更高层次的插件自定义扩展点。这种扩展模式可以让开发者给基础工具平台增加不同的功能。每一个工具生产出来的人工品，比如文件和其他的数据，由一个共同的平台资源模型来协调。</p>
<p>插件的开发者可以从这个架构中获得很多。这个平台管理多种不同的运行时环境，例如不同的操作系统或者工作组服务器环境。插件开发者能够专心完成他们的任务，不用担心有关集成的问题。</p>
<p><b><big><big>平台架构</big></big></b></p>
<p>Eclipse平台本身就是一个子系统，在由一个或者多个插件中实现。这个子系统在一个小型的运行时引擎的上面建造。下图做一个简单的描绘。<br /><img style="max-width: 800px;" src="http://www.zhongzichang.com/wp-content/uploads/2011/09/arch-npi.jpg" /><br />拼凑成这个子系统的插件为给平台增加行为， 而定义了多个扩展点。下表描述这个平台的主要运行时组件，由一个或者多个插件实现。<br />平台运行时&nbsp;&nbsp; &nbsp;定义了扩展点与插件模型。动态发现插件和在一个平台注册表中维护插件及其扩展点的信息。当需要响应用户对平台的操作时，插件被启动。运行时使用OSGi框架实现。<br />资源管理（workspace）&nbsp;&nbsp; &nbsp;为资源的创建和管理，定义的API。这些资源包括项目、文件和目录，都是由工具生成并且保存在文件系统里。<br />工作台UI&nbsp;&nbsp; &nbsp;实现用户纵览平台的座舱。定义了扩展点，为增加UI组件，比如 views 或者 菜单 actions。提供附加的工具（JFace和SWT）来建造用户界面。UI服务是结构化的，因此UI插件的子集能够被用于建造RCA，独立与资源管理和workspace模型。以IDE为中心的插件为纵览和操纵资源，定义了另外的功能。<br />帮助系统&nbsp;&nbsp; &nbsp;像书籍一般，给插件来定义扩展点，能够提供帮助或者其他的文档。<br />团队支持&nbsp;&nbsp; &nbsp;为管理和版本化资源，定义了一个团队编程模型。<br />调试支持&nbsp;&nbsp; &nbsp;定义了一个语言独立的调试模型和UI类，为的是建造调试器和运行器。<br />其他工具&nbsp;&nbsp; &nbsp;其他的插件，比如支持搜索和资源比较，使用XML配置文件执行建造，从服务器那里动态升级平台。</p>
<p><b><big><big>盒子之外</big></big></b></p>
<p>离开了Web，基础平台就是一个IDE，没有什么特别的。<br /><img style="max-width: 800px;" src="http://www.zhongzichang.com/wp-content/uploads/2011/09/emptyworkbench.png" /></p>
<p>它是一个检查平台的最终功能的插件。这就是为什么Eclipse SDK和额外的插件一起装运，来增加SDK的功能。</p>
<p>你的插件可以提供这样的支持，编辑和操作额外的资源类型，例如Java文件、C程序、Word文档、HTML页面和JSP文件。</p>
<p><b><big><big>挑战</big></big></b></p>
<p>我们要求达到一个这样的集成水准，魔法般将独立的开发工具揉合到一个设计套件中。已有的工具可以足够简单的迁移到平台中，不需要强塞硬撬。</p>
<p>平台应该是开放的，用户可以选择工具，并且他们知道供应商在底层平台的开发过程中说了些什么。</p>
<p>它应该足够简单，容易理解，足够强壮，无须额外的粘和剂就支持集成。</p>
<p>提供工具，将平凡常用普通的任务自动化。足够稳定，让业界强壮的工具在其上面建造。非常有用，平台的开发者可以使用它来建造它本身。</p>
<p>上面都是Eclipse的目标。这个手册将帮助你检查Eclipse如何去实现这些想法。</p>
<div class="zemanta-pixie"><img class="zemanta-pixie-img" alt="" src="http://img.zemanta.com/pixy.gif?x-id=a86f874a-4046-8cb2-9c5a-0febbe54baaa" /></div>
]]></content:encoded>
			<wfw:commentRss>http://www.zhongzichang.com/archives/350/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Maven 建造的生命周期</title>
		<link>http://www.zhongzichang.com/archives/335</link>
		<comments>http://www.zhongzichang.com/archives/335#comments</comments>
		<pubDate>Fri, 29 Oct 2010 07:00:38 +0000</pubDate>
		<dc:creator>zhongzichang</dc:creator>
				<category><![CDATA[Maven]]></category>

		<guid isPermaLink="false">http://www.zhongzichang.com/?p=335</guid>
		<description><![CDATA[概念：生命周期，建造过程，目标。 + 建造的生命周期基础 Maven 2.0 的中心概念就是建造的生命周期。项目成品的建造和分发的过程被明确定义。 对于建造一个项目的个人来讲，需要做的事情就是学习一些建造Maven项目的简单命令，以及POM，确保得到想要的结果。 有三个内建的建造生命周期：default, clean 和 site。defalut 生命周期处理你的项目的部署，clean 生命周期处理项目的清理，site生命周期处理你的项目站点文档的创建。 ++ 一个建造的生命周期是由过程组成 每一个建造生命周期由一系列不同的建造过程组成，建造过程表现为生命周期的一个阶段。 例如，default 生命周期拥有下面的建造过程（要获得完成的建造过程的列表 ，参考 “生命周期参考”）： • validate &#8211; 检查项目的正确性和所需的信息是否有效 • compile &#8211; 编译项目的源代码 • test &#8211; 使用适合的单元测试框架来测试编译后的源代码。这些测试不需要代码被打包或者部署 • package &#8211; 将编译后的代码打包成为可分发的格式，例如一个JAR • integration-test &#8211; 根据需要，处理和部署包到一个环境，那里进行集成测试 &#8230; <a href="http://www.zhongzichang.com/archives/335">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>概念：生命周期，建造过程，目标。</p>
<p><strong>+ 建造的生命周期基础</strong></p>
<p>Maven 2.0 的中心概念就是建造的生命周期。项目成品的建造和分发的过程被明确定义。</p>
<p>对于建造一个项目的个人来讲，需要做的事情就是学习一些建造Maven项目的简单命令，以及POM，确保得到想要的结果。</p>
<p>有三个内建的建造生命周期：default, clean 和  site。defalut 生命周期处理你的项目的部署，clean 生命周期处理项目的清理，site生命周期处理你的项目站点文档的创建。</p>
<p><strong>++ 一个建造的生命周期是由过程组成</strong></p>
<p>每一个建造生命周期由一系列不同的建造过程组成，建造过程表现为生命周期的一个阶段。</p>
<p>例如，default 生命周期拥有下面的建造过程（要获得完成的建造过程的列表 ，参考 “生命周期参考”）：</p>
<p>• validate &#8211; 检查项目的正确性和所需的信息是否有效<br />
• compile &#8211; 编译项目的源代码<br />
• test &#8211; 使用适合的单元测试框架来测试编译后的源代码。这些测试不需要代码被打包或者部署<br />
• package &#8211; 将编译后的代码打包成为可分发的格式，例如一个JAR<br />
• integration-test &#8211; 根据需要，处理和部署包到一个环境，那里进行集成测试<br />
• verify &#8211; 执行一些检查，验证包是否有效并且符合质量要求<br />
• install &#8211; 安装包到本地仓库，为让其他的项目可以依赖<br />
• deploy &#8211; 在一个集成获得发行的环境完成，拷贝最终的包到远程仓库，与其他的开发者或者项目共享</p>
<p>这些建造过程（增加的其他建造过程没有在这里展示）按照一定的顺序执行，来完成default生命周期。上面给出的建造过程，这表示当default生命周期被使用，Maven将首先检查项目，然后尝试编译源代码，运行相关的测试，打包二进制文件，运行集成测试，验证包，安装验证后的包到本地仓库，然后在一个指定的环境部署安装的包。</p>
<p>要完成上面所有的任务，你仅仅需要调用最后的建造过程，在这个例子中，就是 deploy :</p>
<p>mvn deploy</p>
<p>这是因为你调用这个建造过程，不仅仅指定的建造过程被执行，哪些排在该建造过程前面的所有建造过程都会被执行。因此，执行</p>
<p>mvn integeration-test</p>
<p>将执行所有在它之前的建造过程（validate，compile，package，等等）。</p>
<p>这个生命周期还有很多建造过程，将在下面的章节讨论。</p>
<p>同样要注意的是，同样的命令可以在一个多模块的情景中使用（例如，一个项目有一个或者多个子项目）。例如：</p>
<p>mvn clean install</p>
<p>这个命令也会在所有的子项目中执行 clean, 然后是 instlal （包括所有前面的步骤）。</p>
<p><strong>++ 建造过程是由一组目标组成</strong></p>
<p>然而，构建过程负责建造生命周期的一个具体的步骤，以何种方式履行这些责任可能有所不同，因此，通过声明一些目标来绑定到这些建造过程的方法来完成。</p>
<p>一个目标表现为一个具体的任务（细于建造过程）有利于项目的建造和管理。它可以被绑定到零到多个建造过程。没有绑定到建造过程的目标可以在建造生命周期之外以直接调用的方式执行。执行的顺序依赖于目标的顺和被调用的建造过程s。例如，考虑下面的命令。clean 和 package 参数一个建造过程，而 dependency:copy-dependencies 是一个目标。</p>
<p>mvn clean dependency:copy-dependencies package</p>
<p>clean 过程首先被执行（这表示clean生命周期签名的所有前面的过程都被执行，加上 clean 本身），然后是 dependency:copy-dependencies 目标，最后执行 package 过程（default生命周期所有前面的过程被执行，包括package本身）。</p>
<p>此外，如果一个目标被绑定到多个建造过程，这个目标将在所有这些过程中被调用。</p>
<p>一个建造过程可以被绑定零个或者多个目标。如果一个建造过程没有绑定任何目标，那么这个建造过程将不会被执行。但如果绑定了一个获得多个目标，它将执行所有的目标（注意：在 Maven 2.0.5 和以上的版本，多个绑定到同一个过程的目标是按照POM里面声明的顺序来执行，然而，同一个插件的多个实例并不会被支持。在Maven 2.0.11 和以上的版本，同一个插件的多个实例被分组执行和排序）。</p>
<p><strong>+ 设置你的项目让其使用建造生命周期</strong></p>
<p>建造生命周期用起来很简单，但当你给一个项目构造一个Maven建造，你如何给这些建造过程赋予任务呢？</p>
<p><strong>++ 打包</strong></p>
<p>首先，最通用的方式，通过POM的元素
<packaging>给你的项目设置打包。有效的打包值分别是 jar, war, ear 和 pom。如果没有指定打包值，缺省是 jar。</p>
<p>每一种打包都包含一系列的目标，绑定到一个具体的过程。例如， jar 打包将绑定下面的目标到 default 生命周期的建造过程。</p>
<p>• process-resources	resources:resources<br />
• compile	compiler:compile<br />
• process-test-resources	resources:testResources<br />
• test-compile	compiler:testCompile<br />
• test	surefire:test<br />
• package	jar:jar<br />
• install	install:install<br />
• deploy	deploy:deploy</p>
<p>这几乎是标准绑定的集合；然而，有些打包的处理是很不一样的。例如一个项目是纯 metadata（打包值是 pom），仅仅绑定目标到 install 和 deploy 过程（要获得一个完成的列表，关于一些打包类型的目标到建造过程，参考生命周期参考）。</p>
<p>注意，为了让一些打包类型有效，你需要在你的POM的<build>段中包含一个具体的插件，并且给插件指定<executions>true</executions>。<br />
一个插件的例子，需要Plexus 插件，它提供一个 plexus-application 和 plexus-service 打包。</p>
<p><strong>++ Plugins</strong></p>
<p>第二种增加目标到建造过程的方法就是在你的项目中配置插件。插件是成品，它给Maven提供目标。一个插件可以有一个或者多个目标，每一个目标表现该插件的一种能力。例如 Compiler 插件有两个目标：compile 和 testCompile。前一个编译你的主要源代码，后一个编译你的测试的代码。</p>
<p>在后面你将看到，插件可以获得信息，指明哪些生命周期过程绑定哪些目标。注意的是，仅仅增加给它自己增加插件是不够的，还需要指明哪些目标是你的建造的一部分。</p>
<p>配置好的目标将增加到已经绑定到生命周期的目标。如果不止一个目标绑定到某个过程，首先执行的是来自打包的，然后是哪些在POM中配置的。注意，你可以使用<executions>元素获得对特定的目标顺序的更多控制。</p>
<p>例如，Modello插件缺省绑定它的目标 modelo:java 到生成源代码的 过程（注意： modello:java 目标生成 Java 源代码）。因此使用 Modello 插件，使用它从一个模型和组合到构建中，你需要增加下面的内容到POM的<build>的
<plugins>段。</p>
<blockquote><p>
&#8230;<br />
<code> &lt;plugin&gt;<br />
   &lt;groupId&gt;org.codehaus.modello&lt;/groupId&gt;<br />
   &lt;artifactId&gt;modello-maven-plugin&lt;/artifactId&gt;<br />
   &lt;version&gt;1.4&lt;/version&gt;<br />
   &lt;executions&gt;<br />
     &lt;execution&gt;<br />
       &lt;configuration&gt;<br />
         &lt;models&gt;<br />
           &lt;model&gt;src/main/mdo/maven.mdo&lt;/model&gt;<br />
         &lt;/models&gt;<br />
         &lt;version&gt;4.0.0&lt;/version&gt;<br />
       &lt;/configuration&gt;<br />
       &lt;goals&gt;<br />
         &lt;goal&gt;java&lt;/goal&gt;<br />
       &lt;/goals&gt;<br />
     &lt;/execution&gt;<br />
   &lt;/executions&gt;<br />
 &lt;/plugin&gt;</code><br />
&#8230;
</p></blockquote>
<p><executions>元素放在那个地方，让你可以根据需要使用不同的配置运行同一个目标多次。单独执行也可以得到一个ID，这样，在继承或配置文件，你可以控制的目标设定是否合并，变成为一个额外的执行申请。</p>
<p>当匹配一个具体过程的多个executions给出，他们将按照POM中指定的顺序执行，继承的executions将首先运行。</p>
<p>现在，在 modello:java 的例子中，仅仅在 generate-sources 过程中有意义。但有些目标不仅仅能在一个过程中使用，缺省这可能是不合理的。对于这个，你可以自己指定过程。例如，你有一个目标 display:time ，在命令行上显示当前时间，你想让它运行在 process-test-resources 过程中，来指明什么时候测试开始。这个配置如下：</p>
<blockquote><p>&#8230;<br />
<code> &lt;plugin&gt;<br />
   &lt;groupId&gt;com.mycompany.example&lt;/groupId&gt;<br />
   &lt;artifactId&gt;display-maven-plugin&lt;/artifactId&gt;<br />
   &lt;version&gt;1.0&lt;/version&gt;<br />
   &lt;executions&gt;<br />
     &lt;execution&gt;<br />
       &lt;phase&gt;process-test-resources&lt;/phase&gt;<br />
       &lt;goals&gt;<br />
         &lt;goal&gt;time&lt;/goal&gt;<br />
       &lt;/goals&gt;<br />
     &lt;/execution&gt;<br />
   &lt;/executions&gt;<br />
 &lt;/plugin&gt;</code><br />
&#8230;</p></blockquote>
<p><strong>+ 生命周期参考</strong></p>
<p>下面列出default，clean 和 site 三个生命周期的所有建造过程，根据指定的点，执行的顺序和列出的顺序一致。</p>
<p><strong>++ Clean Lifecycle</strong></p>
<p>• pre-clean	在实际的项目清理前执行。<br />
• clean	清理上次建造过程中产生的所有文件。<br />
• post-clean	在项目清理后执行。</p>
<p><strong>++ Default Lifecycle</strong></p>
<p>• validate	检查项目是否正确，所需要的信息是否有效。<br />
• initialize	初始化建造的状况，例如设置属性或者创建目录s。<br />
• generate-sources	生成一些编译时包含的源代码。<br />
• process-sources	处理源代码，例如过滤一些值。<br />
• generate-resources	生成源代码。<br />
• process-resources	处理和拷贝资源到目标目录，为打包做准备。<br />
• compile	编译源代码，放入目标目录。<br />
• process-classes	对编译后的文件的后期处理，例如对Java的类进行字节码增强。<br />
• generate-test-sources	生成测试代码。<br />
• process-test-sources	处理测试代码，例如过滤某些值。<br />
• generate-test-resources	创建测试资源。<br />
• process-test-resources	处理和拷贝资源到目标目录。<br />
• test-compile	编译测试代码，放入测试目标目录。<br />
• process-test-classes	对编译后的生成的测试文件进行后期处理，例如对Java类进行字节增强。Maven 2.0.5 和以上。<br />
• test	使用测试框架进行单元测试。这些测试不需要代码打包或部署。<br />
• prepare-package	打包前的准备。根据具体需要。通常是解包，处理不同包的不同版本。<br />
• package	打包编译后的代码，以可发布的格式，例如一个JAR。<br />
• pre-integration-test	集成测试前的准备。可能包括设置需要的环境。<br />
• integration-test	处理和部署包到一个可以进行集成测试的环境。<br />
• post-integration-test	集成测试后处理。可能包含清理环境的操作。<br />
• verify	检验包的有效性，是否符合质量的要求。<br />
• install	在本地仓库安装包，给使用这个依赖的本地项目使用。<br />
• deploy	在一个集成或者发行环境中完成。拷贝最终的包到远程仓库，共享给其他的开发者和项目。</p>
<p><strong>++ Site Lifecycle</strong></p>
<p>• pre-site	在站点文档生成前执行。<br />
• site	生成项目的站点文档。<br />
• post-site	在站点文档生成后执行，准备站点的俄部署。<br />
• site-deploy	部署生成的站点文档到远程的Web服务器。</p>
<p><strong>+ 内建的生命周期绑定</strong></p>
<p>缺省，一些过程拥有绑定到本身的目标。对于default生命周期，这些绑定依赖打包值。下面是一些 目标到建造过程的绑定。</p>
<p><strong>++ Clean Lifecycle Bindings</strong></p>
<p>• clean	clean:clean</p>
<p><strong>++ Default Lifecycle Bindings &#8211; Packaging ejb / ejb3 / jar / par / rar / war</strong></p>
<p>• process-resources	resources:resources<br />
• compile	compiler:compile<br />
• process-test-resources	resources:testResources<br />
• test-compile	compiler:testCompile<br />
• test	surefire:test<br />
• package	ejb:ejb or ejb3:ejb3 or jar:jar or par:par or rar:rar or war:war<br />
• install	install:install<br />
• deploy	deploy:deploy</p>
<p><strong>++ Default Lifecycle Bindings &#8211; Packaging ear</strong></p>
<p>• generate-resources	ear:generateApplicationXml<br />
• process-resources	resources:resources<br />
• package	ear:ear<br />
• install	install:install<br />
• deploy	deploy:deploy</p>
<p><strong>++ Default Lifecycle Bindings &#8211; Packaging maven-plugin</strong></p>
<p>• generate-resources	plugin:descriptor<br />
• process-resources	resources:resources<br />
• compile	compiler:compile<br />
• process-test-resources	resources:testResources<br />
• test-compile	compiler:testCompile<br />
• test	surefire:test<br />
• package	jar:jar and plugin:addPluginArtifactMetadata<br />
• install	install:install and plugin:updateRegistry<br />
• deploy	deploy:deploy</p>
<p><strong>++ Default Lifecycle Bindings &#8211; Packaging pom</strong></p>
<p>• package	site:attach-descriptor<br />
• install	install:install<br />
• deploy	deploy:deploy</p>
<p><strong>++ Site Lifecycle Bindings</strong></p>
<p>• site	site:site<br />
• site-deploy	site:deploy</p>
<p><strong>++ References</strong></p>
<p>完整的Maven生命周期在模块 maven-core 文件components.xml中定义，可通过 Maven 2.2.0 和 Maven 3.0.x 的 SVN分支查看。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zhongzichang.com/archives/335/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Eclipse 的 Maven 插件</title>
		<link>http://www.zhongzichang.com/archives/333</link>
		<comments>http://www.zhongzichang.com/archives/333#comments</comments>
		<pubDate>Thu, 28 Oct 2010 06:31:26 +0000</pubDate>
		<dc:creator>zhongzichang</dc:creator>
				<category><![CDATA[Maven]]></category>

		<guid isPermaLink="false">http://www.zhongzichang.com/?p=333</guid>
		<description><![CDATA[m2eclipse=>eclipse m2e m2elipse是第一个，也是最成熟的一个项目，集成 Maven 到 Eclipse IDE。在 EPL 1.0 下发行。 特点包括： 在Eclipse内部进行Maven建造 基于Maven的pom.xml来进行Eclipse的依赖管理 从Eclipse工作空间解释Maven的依赖，无须安装到本地Maven仓库 从远程仓库自动下载需要的依赖和源代码 提供的向导，支持创建新Maven项目，pom.xml和为已有的项目提供Maven支持 在远程仓库上快速搜索依赖 根据类和包的名字，查询需要的依赖和JARs，在Java编辑器内快速修整 与其他的Eclipse工具集成，例如 WTP, AJDT, Mylyn, subclipse 等 已迁移为 Eclipse 的 m2e 。 Eclipse IAM Eclipse IAM 一个新的 Apache Maven 插件，用新的方法来集成 Maven 到 Eclipse &#8230; <a href="http://www.zhongzichang.com/archives/333">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><strong>m2eclipse=>eclipse m2e</strong></p>
<p>m2elipse是第一个，也是最成熟的一个项目，集成 Maven 到 Eclipse IDE。在 EPL 1.0 下发行。</p>
<p>特点包括：</p>
<ul>
<li>在Eclipse内部进行Maven建造</li>
<li>基于Maven的pom.xml来进行Eclipse的依赖管理</li>
<li>从Eclipse工作空间解释Maven的依赖，无须安装到本地Maven仓库</li>
<li>从远程仓库自动下载需要的依赖和源代码</li>
<li>提供的向导，支持创建新Maven项目，pom.xml和为已有的项目提供Maven支持</li>
<li>在远程仓库上快速搜索依赖</li>
<li>根据类和包的名字，查询需要的依赖和JARs，在Java编辑器内快速修整</li>
<li>与其他的Eclipse工具集成，例如 WTP, AJDT, Mylyn, subclipse 等</li>
</ul>
<p>已迁移为 Eclipse 的 m2e 。</p>
<p><strong>Eclipse IAM</strong></p>
<p>Eclipse IAM 一个新的 Apache Maven 插件，用新的方法来集成 Maven 到 Eclipse IDE 和其他的 Eclipse 插件（JDT，WTP，Candy for Appfuse，&#8230;）一起，同样，让其他的 Eclipse 插件开发者方便的访问 Maven 的功能部件。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zhongzichang.com/archives/333/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Eclipse GUI 线程方面的问题</title>
		<link>http://www.zhongzichang.com/archives/325</link>
		<comments>http://www.zhongzichang.com/archives/325#comments</comments>
		<pubDate>Thu, 21 Oct 2010 03:40:24 +0000</pubDate>
		<dc:creator>zhongzichang</dc:creator>
				<category><![CDATA[Eclipse]]></category>

		<guid isPermaLink="false">http://www.zhongzichang.com/?p=325</guid>
		<description><![CDATA[当做 widget toolkit 方面的工作时，理解底下的线程模型很重要，它用来读取和分发平台的GUI事件。当使用Java线程时，UI线程的实现影响到应用必须遵循的规则。 本地时间分发 操作系统将时间分发给应用程序 SWT UI 线程 UI有自己的独立的线程，Display 里创建。 应用的主线程负责负责处理 event loop，SWT 应用一般都有下面对结构： public static void main(String[] args){ Display display = new Display(); Shell shell = new Shell(display); shell.open(); // start the event loop. We stop when th &#8230; <a href="http://www.zhongzichang.com/archives/325">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>当做 widget toolkit 方面的工作时，理解底下的线程模型很重要，它用来读取和分发平台的GUI事件。当使用Java线程时，UI线程的实现影响到应用必须遵循的规则。</p>
<p><strong>本地时间分发</strong></p>
<p>操作系统将时间分发给应用程序</p>
<p><strong>SWT UI 线程</strong></p>
<p>UI有自己的独立的线程，Display 里创建。</p>
<p>应用的主线程负责负责处理 event loop，SWT 应用一般都有下面对结构：</p>
<p><code>public static void main(String[] args){<br />
	Display display = new Display();<br />
	Shell shell = new Shell(display);<br />
	shell.open();<br />
	// start the event loop. We stop when th euser has done<br />
	// something to dispose our window.<br />
	while(!shell.isDisposed()) {<br />
		if(!display.readAndDispatch()) {<br />
			display.sleep();<br />
		}<br />
	}<br />
	display.dispose();<br />
}</code></p>
<p><strong>在一个非UI 线程那里执行代码</strong></p>
<p>同步<br />
syncExec(Runnable)</p>
<p>非UI线程需要从 UI 代码那里获得返回值，或者 在返回到线程之前，确保 runnable 运行完成。</p>
<p>异步<br />
asyncExec(Runnable)</p>
<p>在应用程序需要执行一些UI操作，并不依赖操作的完成再继续。</p>
<p>下面是一个使用这些方法的演示：<br />
<code>   // do time-intensive computations<br />
   ...<br />
   // now update the UI. We don't depend on the result,<br />
   // so use async.<br />
   display.asyncExec (new Runnable () {<br />
      public void run () {<br />
         if (!myWindow.isDisposed())<br />
            myWindow.redraw ();<br />
      }<br />
   });<br />
   // now do more computations<br />
   ...</code></p>
<p>一个好的练习，使用 asyncExec 在你的 runnable 里面检查 你的 widget 是否已经被销毁。由于在UI线程内部，调用asyncExec和你的runnable的执行时间内，其他的事情可能发生，因此，你不能确认在你的runnable执行期间，你的widget是什么状态。</p>
<p><strong>工作台和线程</strong></p>
<p>当你从底部往上，实现一个 SWT 应用，由于你控制了event loop 的创建和fork计算线程的决定，线程的规则就变得非常明确。</p>
<p>当你将插件的代码发布到工作台，事情就有一点复杂了。当使用平台UI类s，下面的规则可以被考虑成“承诺的规则“，虽然随着版本的更新，这些规则会有一些异常：</p>
<p>• 一般情况下，你增加到平台的任何工作台UI扩展，都在工作台的UI线程内执行，除非它们与线程s或者背景工作s都特别相关（例如背景工作进度表示）。<br />
• 如果你从工作台那里接收到一个事件，但不敢保证，它在工作台的UI线程内执行。查阅javadoc里面的特定的类，这个类定了监听器或者事件。如果没有描述线程的相关文档，并且该类明显是一个UI相关的测类，你可以期望这个事件在工作台线程内到达。<br />
• 同样，一个平台UI库不需要考虑线程安全，否则特别给它做文档。注意，大多数的平台UI类从触发事件的调用线程分发监听器。工作台和JFace API的调用不检查调用者是否在UI线程内。如果你调用从一个非UI线程里面调用一个触发事件的方法，你的插件将产生一个问题。这种情况，SWT触发一个SWTException。一般情况下，避免从另一个线程那里调用平台UI代码，除非javaodc特别允许。<br />
• 如果你的插件 fork一个计算线程或者使用一个工作台的job，必须使用 Display 的 asyncExec(Runnable) 或者 syncExec(Runnable)方法（为工作台，JFace或者SWT调用任意API），除非相关的API特别允许被背景线程call-in。<br />
• 如果你的插件使用JFace的IRunnableContext接口调用一个进度监视器和运行一个操作，它提供一个参数，指明是否为运行的操作fork一个计算线程。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zhongzichang.com/archives/325/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

