淘宝商城(天猫)高级技术专家.3年研发+3年性能测试调优/系统测试+4年团队管理与测试架构、研发系统实践. 新舞台新气象, 深化测试基础架构及研发架构,希望能在某个技术领域成为真正的技术大牛。欢迎荐才http://bbs.51testing.com/viewthread.php?tid=120496&extra=&page=1 .邮件: jianzhao.liangjz@alibaba-inc.com,MSN:liangjianzhao@163.com.微博:http://t.sina.com.cn/1674816524

发布新日志

  • maven job命令行执行外部shell

    2012-03-08 11:02:17

     目前编译环境是

    [maven3@inc-platform-dev-144-9 hudson-2.0.1_win]$ mvn -v

    Apache Maven 3.0.3 (r1075438; 2011-03-01 01:31:09+0800)

    Maven home: /home/maven3/apache-maven-3.0.3

    Java version: 1.6.0_25, vendor: Sun Microsystems Inc.

    Java home: /usr/alibaba/install/jdk1.6.0_25/jre

    Default locale: en_US, platform. encoding: ISO-8859-1

     

     

    ) hudson.maven.agent.Main

     

     

    增加callShell函数的2个版本。

     

        //see http://www.devdaily.com/java/java-exec-processbuilder-process-2

        //fixed exec linux shell hang

        //多线程版

        private static int  callShell_mt(String cmd) throws IOException,

        InterruptedException {

           List commands = new ArrayList();

           System.out

                  .print(" ***warning!only support shell!callShell start by liangjz.*** ");

           commands.add("/bin/sh");

           commands.add("-c");

           commands.add(cmd);

           SystemCommandExecutor commandExecutor = new SystemCommandExecutor(commands);

            int shellExitStatus = commandExecutor.executeCommand();

            // stdout and stderr of the command are returned as StringBuilder objects

            StringBuilder stdout = commandExecutor.getStandardOutputFromCommand();

            System.out.println("The numeric result of the command was: " + shellExitStatus);

            System.out.println(stdout);

            return shellExitStatus;

        }

        private static int callShell(String cmd) throws IOException,

               InterruptedException {

           List commands = new ArrayList();

           System.out

                  .print(" ***warning!support shell!may be waiting  long time ,please!!callShell start by liangjz.*** ");

           commands.add("/bin/sh");

           commands.add("-c");

           commands.add(cmd);

           ProcessBuilder pb = new ProcessBuilder(commands);

           pb.redirectErrorStream(true); // use this to capture messages sent to

                                       // stderr

           Process shell = pb.start();

           InputStream shellIn = shell.getInputStream(); // this captures the

                                                     // output from the

                                                     // command

           int shellExitStatus = shell.waitFor(); // wait for the shell to finish

                                              // and get the return code

     

           // at this point you can process the output issued by the command

           // for instance, this reads the output and writes it to System.out:

           int c;

           while ((c = shellIn.read()) != -1) {

               System.out.write(c);

           }

           // close the stream

           try {

               shellIn.close();

           } catch (IOException ignoreMe) {

     

           }

           System.out.print(" *** callShell End by liangjz,return  " + shellExitStatus);

           return shellExitStatus;

        }

     

     

     

     

    //launch根据mvn命令行传递入的参数才触发调用外部shell.

     

    public static int launch(String[] args) throws NoSuchMethodException,

               IllegalAccessException, NoSuchRealmException,

               InvocationTargetException, ClassNotFoundException {

           // ClassWorld world = ClassWorldAdapter.getInstance( launcher.getWorld()

           // );

     

           ClassWorld world = launcher.getWorld();

     

           Set builtinRealms = new HashSet(world.getRealms());

           boolean callShell = false;

           int callShellRet=-1;

           try {

               System.out.println("----- hudson.maven.agent.Main.launch start by  liangjz----");

               String libs = null;

               String workspace=null;

               String apps=null;

                            String crid="0";

               StringBuilder sb=new StringBuilder();

               sb.append("'");

               for (int i = 0; i < args.length; i++) {

                  //System.out.println("arg" + i + "=" + args[i]);

                  if (args[i].startsWith("-DlibsOrder")) {

                      String[] tmpArr = args[i].split("=");

                      if (tmpArr.length == 2) {

                              callShell = true;

                         libs = tmpArr[1];

                      }

                  }else if(args[i].startsWith("-Dapps")){

                      String[] tmpArr = args[i].split("=");

                      if (tmpArr.length == 2) {

                         apps = tmpArr[1];

                      }

                  }else if(args[i].startsWith("-DWORKSPACE")){

                      String[] tmpArr = args[i].split("=");

                      if (tmpArr.length 查看(4124) 评论(0) 收藏 分享 管理

  • 彻底删除hudson job的方法

    2012-03-08 10:56:47

    官方hudson2.0.1删除job,并没有删除各次build的历史记录。本次改动hudson代码删除在master上的配置文件及各个还残留build记录的 slave上的build记录。

     

    )   hudson.model.AbstractProject.performDelete()

     

    修改为获取所有的build记录上的Node并执行删除操作。

     

    @Override

        protected void performDelete() throws IOException, InterruptedException {

            // prevent a new build while a delete operation is in progress

            makeDisabled(true);

           //modify by liangjz

           //FilePath ws = getWorkspace();

           //if(ws!=null) {       

            /*

                Node n = getLastBuiltOn();

                getScm().processWorkspaceBeforeDeletion(this, ws, on);

                if(on!=null)

                    on.getFileSystemProvisioner().discardWorkspace(this,ws);

                 */

             Map<Node,FilePath>  nfMap = getAllBuiltOn();

             for(Map.Entry<Node,FilePath> entry:nfMap.entrySet())

             {

                 Node n=entry.getKey();

                 FilePath fp=entry.getValue();

                     getScm().processWorkspaceBeforeDeletion(this, fp, n);

                     if(n!=null)

                         n.getFileSystemProvisioner().discardWorkspace(this,fp);

                 }            

            //}

            super.performDelete();

       }

     

    二)hudson.model.Job 获取所有的曾经build过的节点及workspace目录

     

    public Map<Node,FilePath> getAllBuiltOn() {

            // where was it built on?

           List allBuild = getAllBuild();

           Map<Node,FilePath> map=new HashMap<Node,FilePath>();

            Set<Node> nodes=new HashSet<Node>();

            for(Object o: allBuild){

            AbstractBuild b=(AbstractBuild) o;

            Node n= b.getBuiltOn();          

            if(!nodes.contains(n)){

                 FilePath ws=b.getWorkspace();

                 if(ws!=null){

                     map.put(n,ws);

                     nodes.add(n);

                 }

            }           

            }    

            return map;   

    }

     

    三)  Hudson.FileSystemProvisioner

     

    此处需要实现序列化。并且各个slave重新下载slave.jar且重连。

     

    discardWorkspace 加入激活slave删除文件夹的功能。

     

    public static final class Default extends FileSystemProvisioner implements   Serializable {

            /**

     

           public void prepareWorkspace(AbstractBuild<?, ?> build, FilePath ws, TaskListener listener) throws IOException, InterruptedException {

            }

             

            public void discardWorkspace(AbstractProject<?, ?> project, FilePath ws) throws IOException, InterruptedException {

            //add by liangjz,递归删除文件参考ZFSProvisioner

            ws.act(new FileCallable<Void>() {

                    public Void invoke(File f, VirtualChannel channel) throws IOException {

                        if(f!=null){

                           Util.deleteRecursive(f);

                        }                      

                        return null;

                    }

                });

            }

     

     

     

  • tomcat url编解码处理方法

    2010-10-04 07:58:12

    Tomcat6安装目录/conf/server.conf 默认的connector配置如下,

     

    <Connector port="8080" protocol="HTTP/1.1"

                   connectionTimeout="20000"

                   redirectPort="8443"  />

     

    默认情况下其URIEncoding =”ISO8859-1”

    为了确保web客户端和服务器编解码正常,在客户端肯定是utf8编码的情况下,处理方式有2

     

    1)      tomcat connector采用默认配置URIEncoding =”ISO8859-1”

     

    client端编码:

    URLEncoder.encode(description,"UTF-8");

     

    server端解码:(接收到的为ISO8859-1编码的字符串)

    String description = request.getParameter("description");

    decDescription = new String(description.getBytes("ISO8859-1"), "UTF-8");

    2)      修改tomcat connector 配置URIEncoding =”UTF-8”

     

    client:

    URLEncoder.encode(description,"UTF-8");

     

    Server端:

    String description = request.getParameter("description");

    //此处接收到的description即为UTF-8格式了。

  • 定制 findbugs规则

    2010-04-04 15:51:41

    这类文章极少,字节码操作需要对becl库及jvm 字节码操作有一定常识。参考:

    http://blog.csdn.net/lywybo/archive/2010/03/01/5335748.aspx

    http://javadevelopmentforthemasses.blogspot.com/2008/09/custom-findbugs-detectors-and-maven.html

    https://www.ibm.com/developerworks/cn/java/j-findbug2/

     

    ibm介绍的原理实用,但配置过时;支付宝朋友写的message.xml/findbugs.xml不够详细且有笔误。

     

    1.1       准备

    下载findbugs: http://sourceforge.net/projects/findbugs/files/findbugs/1.3.9/findbugs-1.3.9.zip/download

     

    修改build.xml ,去除所有的validate依赖。执行ant 编译。

    eclipse引入findbugs工程

     

    1.2       实现类

    直接在findbugs目录中增加类

     

    package edu.umd.cs.findbugs.detect;

    import org.apache.bcel.classfile.Code;

    import edu.umd.cs.findbugs.BugInstance;

    import edu.umd.cs.findbugs.BugReporter;

    import edu.umd.cs.findbugs.bcel.OpcodeStackDetector;

     

    /**

     * @author bo

     * 这个规则类用于判断System.outSystem.error这种情况

     */

    public class ForbiddenSystemClass extends OpcodeStackDetector {

     BugReporter bugReporter;

     

     public ForbiddenSystemClass(BugReporter bugReporter) {

      this.bugReporter = bugReporter;

     }

     

     /**

      * visit方法,在每次进入字节码方法的时候调用

      * 在每次进入新方法的时候清空标志位

      */

     @Override

     public void visit(Code obj) {

      super.visit(obj);

     }

     

     /**

      * 每扫描一条字节码就会进入sawOpcode方法

      *

      * @param seen  字节码的枚举值

      */

     @Override

     public void sawOpcode(int seen) {

      if (seen == GETSTATIC) {

       if (getClassConstantOperand().equals("java/lang/System")

               && (getNameConstantOperand().equals("out") || getNameConstantOperand().equals("error"))) {

        BugInstance bug = new BugInstance(this, "ALP_SYSTEMCLASS", NORMAL_PRIORITY).addClassAndMethod(this)

                .addSourceLine(this, getPC());

        bug.addInt(getPC());

        bugReporter.reportBug(bug);

       }

      }

     }

    }

    1.3       修改etc目录配置文件findbugs.xmlmessage.xml

    不支持中文注释。

    findbugs.xml 增加内容。

    <Detector class="edu.umd.cs.findbugs.detect.ForbiddenSystemClass" 

       speed="fast"

         reports="ALP_SYSTEMCLASS"

         hidden="false" />

     

    <BugPattern abbrev="LIANGJZFORBIDDENSYSTEMCALSS" type="ALP_SYSTEMCLASS" category="EXPERIMENTAL"  />

     

     

    Message.xml增加:

     

    <Detector class="edu.umd.cs.findbugs.detect.ForbiddenSystemClass">

       <Details>

        <![CDATA[

        <p>category:detector find System.out/System.error

        <p>please use log4j

        ]]>

       </Details>

      </Detector>

     

    <BugPattern type="ALP_SYSTEMCLASS">

        <ShortDescription>short desc:System.out/error</ShortDescription>

        <LongDescription>class={0},method {1}long desc:System.out,please use log4j</LongDescription>

        <Details>

      <![CDATA[

        <p>detail info see log4j document</p>

      ]]>

        </Details>

      </BugPattern>

     

     

     

    1.4       findbugs图形化界面测试

    点击bin/finbugs.bat,打开扫描的.class目录。看到扫描带 System.out 或者System.error.class放到experimental类错误时,验证成功。

     

    1.5       替换eclipse findbugs-plugin.jar文件

    winrar打开

    D:\devtools\eclipse_3.5.1\plugins\edu.umd.cs.findbugs.plugin.eclipse_1.3.9.20090821\findbugs-plugin.jar message.xml,findbugs.xml,z加入二进制的edu.umd.cs.findbugs.detect. ForbiddenSystemClass

     

    重启elipse,还需要确保experimental类的错误能在findbugs窗口展现: windows->preferences->java->findbugs->reporter configuration上的experimental选项勾上。

     

     

     执行findbugs扫描.class,看到结果出现..

     

Open Toolbar