??xml version="1.0" encoding="utf-8" standalone="yes"?> Z说明问题Q我Ҏ的设定两个构建时参数:
1.architexa 没有对编译后的代码?先用java decompiler 反编译出如下的类:
2.修改RSECorecȝҎ:
2 {
3 if (!AccountStatusUtils.testAccountValid()) {
4 String email = AccountSettings.getStoredAccountEmail();
5 AccountSettings.getStoredAccountPassword();
6 if ((email != null) && (email.length() > 0))
7 AccountErrorMsgs.displayErr("Account Has Expired ");
8 return false;
9 }
10 return true;
11 }
12
2 {
3 return true;
4 }
3.修改ConnectAccountDialogcȝ代码(反编译后的代码有炚w,q里不列Z)Q最l改成如下即?
2 this.emailEntered = this.emailField.getText();
3 this.passwordEntered = this.passwordField.getText();
4
5 AccountConnection ac = new AccountConnection();
6 if (this.enableOnOK) ac.setMenuToDisable(!this.disableOnCancel);
7 super.okPressed();
8 }
~译后将上述两个cL到对应的jar中,重启eclipse.
4.在architexa的认证对话框Q输入Q意email和password,architexa 重建烦?
5.在某个javacȝ上下文菜单中Q可以看到Open in Diagram 可以生成类的布局图,cd和序列图?可以通过工具栏上的button来输出图?
下面贴几个通过q个插g构成的图Q欣赏下
]]>
1.下蝲
hudson的官方网?a target="_blank">https://hudson.dev.java.net/下提供了下蝲
2.安装
hudson以war包的方式提供,因此安装方式极其单,直接攑ֈ服务器的相应目录?q里攑ֈtomcat的webapp?启动后,讉Khttp://localhost:8088/hudson 可以q入hudson的控制台面.
4.l织待构建的目
q里我们创徏一个最为简单的d.q个d的目的是构徏一个标准的java工程Q将其中的源码编译,打包{?
回顾下一般的、最为简单的开发流E?开发h员开发代码,然后利用诸如ant,mvn{负责构建系l?然后执行试,最后发布到服务器上.通常Q每个项目都会有一个完整的脚本来自动化的做qg?如何驱动自动化脚本的执行(什么时间点,以什么频?理构徏l果)Q是hudson提供l我们的功能Qhudson不关注特定一ơ构建的内部q程,q对hudson是透明?目前Qhudson通过插g的方式,提供了对Zant 、mvn{常见构建工L支持.本质上,hudson是一个Q务管理和驱动执行工具,只不q,它驱动的软g开发流E中的构建等q程.
准备:解决我们特定一ơ构ZQ做什么的问题.
Z试的目的,我们创徏一个示例java工程,l构如下:
此项目的采用ant,构徏,ant脚本如下:
<?xml version="1.0" encoding="UTF-8"?>
<project basedir="." name="build.hudsondemo">
<!-- =================================
target: compile
================================= -->
<target name="compile" depends="prepare" description="compile the project to the bin">
<javac debug="true" destdir="${basedir}/bin">
<src path="${basedir}/src" />
<src path="${basedir}/test" />
<classpath>
<fileset dir="${basedir}/lib">
<include name="*.jar"/>
</fileset>
</classpath>
</javac>
</target>
<!-- =================================
target: jar
================================= -->
<target name="jar" depends="compile" description="jar the project">
<mkdir dir="${basedir}/target"/>
<jar destfile="${basedir}/target/hudsondemo_${common.version}.jar">
<fileset dir="${basedir}/bin" />
</jar>
</target>
<!-- =================================
target: prepare
================================= -->
<target name="prepare" depends="clean" description="prepare the jar to the lib">
<copy todir="${basedir}/lib">
<fileset dir="${common.libs.dir}">
<include name="*.jar"/>
</fileset>
</copy>
</target>
<!-- =================================
target: prepare
================================= -->
<target name="clean">
<delete dir="${basedir}/bin"></delete>
<delete dir="${basedir}/lib"></delete>
<mkdir dir="${basedir}/bin" />
<mkdir dir="${basedir}/lib" />
</target>
</project>
common.libs.dir 指出从什么位|获取编译项目所需要的jar
common.version 指出构徏的jar的版本号.
5.配置hudson的通用配置
Ҏ使用插g的多,通用配置数量同,对上q的CZ目,我们需要配|?nbsp;ant 和jdk(可?如果需要指定用特定的jdk构徏pȝ的话).
点击hudson主页面右上角的manger hudson,q入配置面,有多w|可以处理,但是目前仅仅需要用到System configurate 功能.在System configurate面Q可以如下的配置:
贴此囄目的是需要关注下home directoryq个配置Q默认是当前用户目录下的.hudson,可以更改Q一般在环境变量中设定一个HUSDON_HOME卛_Q同时将原有目录下文件copy到新目录下,重启hudson卛_.也可以用其他的方式,比如讑֮容器参数{来指定.
上述配置取默认既?
配置jdk:
配置ant:
6. 创徏构徏d
hudson能提供的功能都以d存在.点击右上角的new job,构Z个新的Q?
输入d名称Qƈ选择W二?
配置d:解决如何安排构徏d的执行的问题.
首先Q我们需要指定如何保留构建历?一U是Z旉的,保留多少天,一U是Zơ数的,保留自当前开始多次以内?q里我们选择保留最?ơ构?
再次Q我们需要指定利用什么版本ant执行构徏Q同时指定构建时参数.
ant version 版本中,使用了在通用配置部分配置的ant.
targets 中,指明了,每次构徏旉要完成的target,可以指定多个target.
build file 指明了,使用什么样的ant完成实际的构E?
properties 指明了ant脚本中的使用的运行时参数.q些参数可以使用变量替换,hudson 会解析出实际的值再传给ant.
q就是这个Q务可以执行的最基本配置,保存,q点d上角的build new ,可以立即执行一个构?构徏l果如下:
U色表示p|构徏,如果p|Q可以在%HUDSON_HOME%\jobs\下查看对应Q务构建的日志来排查问?
8. 两个可能l常需要关注的配置.
1.每个job?workspace.
如果不指定绝对\径,配置的ant{脚本就是相对这个工作空间的.在上面的例子中工作空间的用处不大Q但是在一些其他类型的构徏Q比如从svn中签Z码构建时Q用处就体现出来了,另外,一些hudson的插Ӟ所利用的文?构徏脚本生成,q些插g不会d注文件生,而是对这些文件做二次处理)都是攑ֈ工作I间?工作I间相当与构建系l和hudson的一个交中?推荐是每个项目有自己独立的工作空?
2.自动构徏的频率设?br />
也就是什么时候触发构建,三种方式:
当别的项目构建完毕后发生构徏
利用cron表到式来指定频率,对cron表达式不熟悉的话Q可以参考quartz(hudson内部使用的调度框?相关的文?
scm(svn、cvs{?的状态,如果到变化Q自动发生构?
借助husdon,基本能做到无人值守构徏和部|Ԍ不少插g可以利用Q也可以开发自q插g.上面的仅仅是一个例子而与Q如果要应对实际工作中的问题Q得好好研究才行.
]]>
1.~写一个服务,实现如下的接?/p>
public interface CommandProvider {
2 /**
3 Answer a string (may be as many lines as you like) with help
4 texts that explain the command.
5 */
6 public String getHelp();
7
8}
如果惛_义helloҎ,可以如下实现该接?
import java.util.Dictionary;
import java.util.Properties;
import org.eclipse.osgi.framework.console.CommandInterpreter;
import org.eclipse.osgi.framework.console.CommandProvider;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
public class Activator implements BundleActivator,CommandProvider {
BundleContext bundleContext=null;
public void start(BundleContext context) throws Exception {
System.out.println("start
" +context.getBundle().getLocation());
bundleContext=context;
context.registerService(CommandProvider.class.getName(), new AntherCommandProvider(), null);
Dictionary dictionary=new Properties();
dictionary.put(Constants.SERVICE_RANKING, 10);
context.registerService(CommandProvider.class.getName(), this,dictionary);
}
public void stop(BundleContext context) throws Exception {
System.out.println("end
" +context.getBundle().getLocation());
}
public String getHelp() {
return "you are using the help command";
}
public void _helloa(CommandInterpreter intp)
{
intp.println("helloa "+ this.getClass().getName());
}
public void _hello(CommandInterpreter intp) throws Exception {
intp.println("hello " + this.getClass().getName());
}
}
import org.eclipse.osgi.framework.console.CommandInterpreter;
import org.eclipse.osgi.framework.console.CommandProvider;
public class AntherCommandProvider implements CommandProvider {
public void _hello(CommandInterpreter intp)
{
intp.println("hello "+ this.getClass().getName());
}
public String getHelp() {
return null;
}
}
其中,通过CommandInterpretercd的nextArgument()Ҏ可以q代出所有的命o参数.
2.注册服务
如果不将该接口注册ؓ服务Q这个hello命o不产生M作用.注册的服务名U必Lorg.eclipse.osgi.framework.console.CommandProvider.
当系l中存在多个此接口的实现?可以通过SERVICE_RANKING属性来军_了命令执行的序,既有最高值的服务被优先执行.q种方式可以重蝲pȝ中已l存在的同名服务.
3.执行命o
请仔l体会输出结?br />
]]>
L层次,可能有多个模块或者组件构成,不同的组仉Q配|的cd可能一P但是配置的数据不一?那么,如果在配|某个模块时Q不比考虑其他模块的配|情况,那么q个模块拥有开发时的独立?当组件被集成到同一层次部vq行Ӟ配置的合q和重组是一个问?q且Q组仉可能存在依赖关系,q种依赖关系同时产生了依赖组仉配置加蝲的优先问题.
成熟的YӞ一般不会直接将W三方的软g集成Q而是其装后在U_q来,W三方组件的配置往往不具备配|的层次化或者模块独立?在设计第三方lg的集成策略时Q需要考虑使其拥有上述两种能力.
解决上述问题Q方式有很多U?我们谈论比较Ҏ实现的一U?
q种解决Ҏ的基本思\如下:
首先Q设计一个特定的扩展名称的配|文?模块配置索引文g,MCIF,xml格式)Q此配置文g面向的是lgU别Q即每个lg定义自己的MCIF.MCIF中定义若q配|类?卛_U空?每一个名U空间负责完成一c配|,一?一个名U空间对应一个配|获取接?q个名称I间中仅仅配|所x的配|的文g的相对位|?相对此MCIF),q样Q最大化的减了不同配置文g格式对MCIF的媄?
每一个MCIF的根元素拥有一个parent属?指向了上一层次,同一层次的MCIF的parent属性都相同.通过parent属性,配置的层ơ化׃是问题了.
MCIF有两个特D的名称I间:
1.register 定义了所支持的名U空间及其对应的配置解析?q样,此配|框架就可以允许对名U空间进行扩?
2.depends 定义了同一层次的模块间的依赖关p?q个是可选的Q如果没有实现或者配|,同一层次的module即ؓq?
当系l启动时,扫描所有的MCIF,q根据parent属性解析出一个层ơ关p?Ҏ一个层ơ下module,参考相应的depends讄定义Z个依赖关p?
当请求某特定的配|时,Ҏ上述的两个关pd成配|的l合Qƈq回l用?
公司最q的重构中,Zq个思想开发的配置框Ӟ很好完成了多层次Q多lg的配|覆盖问?配置相对以前更清晰、简单,配置q程中的x点大大减?
]]>
长久以来Q看别h的blog不少,虽然有深度的原创不多,也l了我莫大的帮助,本着取于?回馈于斯的精?军_也在|上选择一片信手涂鸦之?几经斟酌,最l敲定了blogjava,希望能将q个blog坚持下去,见证一个尘世迷途小卒的成长历程.
希望不至于虎头蛇?that't all!