Joyce 2015-03-16T09:07:47+00:00 kejinlu@gmail.com 关于Java(selenium)调用autoIt脚本的问题 2015-03-16T00:00:00+00:00 Joyce http://minghongjun.github.io/selenium-autoit-script 先来段autoit代码:

Sleep($CmdLine[1])

编译成exe文件,文件名为sleep.exe,放在c盘根目录下,代码的功能很简单,就是根据传入的时间休眠。cmd下执行:c:\sleep.exe 2000,表示休眠2秒。 我们在Java中调用这个程序:

long time1 = System.currentTimeMillis();
try {
        Runtime.getRuntime().exec("c://sleep.exe 10000");
        long time2 = System.currentTimeMillis();
        System.out.println((time2 - time1) + "毫秒。");
} catch (Exception e) {
        e.printStackTrace();
}

用上面这段代码去调用的话,java不会等待autoit的执行,sleep启动后,继续往下执行,这样几乎没有实际的应用价值。我们通常都是要等autoit去把该做的事情都做完再做后面的事情。

long time1 = System.currentTimeMillis();
try {
        Runtime.getRuntime().exec("c://sleep.exe 10000").waitFor();
        long time2 = System.currentTimeMillis();
        System.out.println((time2 - time1) + "毫秒。");
} catch (Exception e) {
        e.printStackTrace();
}

我们在代码中加入waitFor(),可以达到上面的效果,但是又带来了另外一个问题,玩意autoit执行出了问题,一直不退出怎么办?程序就hang住了。

今天在某QQ群中向高人讨教了一番,知道了如何控制autoit的超时问题,我们可以利用检查内存中是否存在au3进程的方式来做判断程序是否执行完毕,同时加一个超时控制,超时则继续往后执行,下面是demo 代码:

Java代码:

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
 
public class Runau3 {
    public static void main(String[] args) {
            // 执行au3脚本
            // 休眠的那个脚本,脚本所在的目录(秒),等待时间,脚本的休眠时间(毫秒)
            runAu3("sleep.exe", "c://", 5, "10000");
    }

    /**
     * 
     * @param filename
     *            au3的文件名,必须编译成exe
     * @param filepath
     *            au3的文件的路径
     * @param timeout
     *            超时时间(秒)
     * @param args
     *            au3的参数
     */
    public static void runAu3(String filename, String filepath, int timeout,
                    String... args) {
            try {
                    // 如果发现进程,先杀了
                    if (findProcess(filename)) {
                            killProcess(filename);
                    }
                    // 拼装命令
                    String cmd = filename;
                    for (String arg : args) {
                            cmd += " " + arg;
                    }

                    // 执行au3脚本
                    Runtime.getRuntime()
                                    .exec("cmd /C " + cmd, null, new File(filepath));
                    int count = 0;
                    while (findProcess(filename) && count < timeout) {
                            System.out.println(count);
                            Thread.sleep(1000);
                            count++;
                    }
                    // 如果进程未结束,杀了
                    if (findProcess(filename)) {
                            killProcess(filename);
                    }
            } catch (Exception e) {
                    e.printStackTrace();
            }

    }

    /**
     * 查找进程
     * @param processname
     * @return
     */
    public static boolean findProcess(String processname) {
            BufferedReader bufferedreader = null;
            try {
                    Process proc = Runtime.getRuntime().exec(
                                    "tasklist /fi \" imagename eq " + processname + " \" ");
                    bufferedreader = new BufferedReader(new InputStreamReader(proc
                                    .getInputStream()));
                    String line = null;
                    while ((line = bufferedreader.readLine()) != null) {
                            if (line.contains(processname)) {
                                    return true;
                            }
                    }
                    return false;
            } catch (Exception ex) {
                    ex.printStackTrace();
                    return false;
            } finally {
                    if (bufferedreader != null) {
                            try {
                                    bufferedreader.close();
                            } catch (Exception ex) {
                            }
                    }
            }
    }

    /**
     * 杀进程
     * @param processname
     */
    public static void killProcess(String processname) {
            BufferedReader bufferedreader = null;
            try {
                    Process proc = Runtime.getRuntime().exec(
                                    "taskkill /F /IM " + processname);
                    bufferedreader = new BufferedReader(new InputStreamReader(proc
                                    .getInputStream()));
                    String line = null;
                    while ((line = bufferedreader.readLine()) != null) {
                            System.out.println(line);
                    }
            } catch (Exception ex) {
                    ex.printStackTrace();
            } finally {
                    if (bufferedreader != null) {
                            try {
                                    bufferedreader.close();
                            } catch (Exception ex) {
                            }
                    }
            }
    }
}

end

]]>
Selenium借助AutoIt识别(上传/下载)详解 2015-03-16T00:00:00+00:00 Joyce http://minghongjun.github.io/selenium-autoit-details AutoIt目前最新是v3版本,这是一个使用类似BASIC脚本语言的免费软件,它设计用于Windows GUI(图形用户界面)中进行自动化操作。它利用模拟键盘按键,鼠标移动和窗口/控件的组合来实现自动化任务。

官方网站:https://www.autoitscript.com/site/ 从网站上下载AutoIt并安装,安装完成在菜单中会看到图4.13的目录:

图 1 AutoIt菜单

AutoIt Windows Info 用于帮助我们识Windows控件信息。
Compile Script to.exe 用于将AutoIt生成 exe 执行文件。
Run Script 用于执行AutoIt脚本。
SciTE Script Editor 用于编写AutoIt脚本。

<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<title>upload_file</title>
<link href="http://cdn.bootcss.com/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
  <div class="row-fluid">
    <div class="span6 well">
    <h3>upload_file</h3>
      <input type="file" name="file" />
    </div>
  </div>
</body>
<script src="http://cdn.bootcss.com/bootstrap/3.3.0/css/bootstrap.min.js"></script>
</html>

将上面的html代码保存为upload.html文件,通过浏览器打开,效果如下:

图 2

下面以操作upload.html上传弹出的窗口为例讲解AutoIt实现上传过程。

1、首先打开AutoIt Windows Info 工具,鼠标点击Finder Tool,鼠标将变成一个小风扇形状的图标,按住鼠标左键拖动到需要识别的控件上。

图 3 AutoIt Windows Info识别“文件名”输入框控件

图 4 AutoIt Windows Info识别“打开”按钮控件

如图3、4,通过AutoIt Windows Info 获得以下信息。

窗口的title为“选择要加载的文件”,标题的Class为“#32770”。

文件名输入框的class 为“Edit”,Instance为“1” ,所以ClassnameNN为“Edit1”。

打开按钮的class 为“Button”,Instance为“1” ,所以ClassnameNN为“Button1”。

2、根据AutoIt Windows Info 所识别到的控件信息打开SciTE Script Editor编辑器,编写脚本。

;ControlFocus("title","text",controlID) Edit1=Edit instance 1
ControlFocus("选择要加载的文件", "","Edit1")

;Wait 10 seconds for the Upload window to appear
WinWait("[CLASS:#32770]","",10)

;Set the File name text on the Edit field
ControlSetText("选择要加载的文件", "", "Edit1", "D:\\upload_file.txt")
Sleep(2000)

;Click on the Open button
ControlClick("选择要加载的文件", "","Button1");

ControlFocus()方法用于识别Window窗口。WinWait()设置10秒钟用于等待窗口的显示,其用法与WebDriver 所提供的implicitly_wait()类似。ControlSetText()用于向“文件名”输入框内输入本地文件的路径。这里的Sleep()方法与Python中time模块提供的Sleep()方法用法一样,不过它是以毫秒为单位,Sleep(2000)表示固定休眠2000毫秒。ControlClick()用于点击上传窗口中的“打开”按钮。

AutoIt的脚本已经写好了,可以通过菜单栏“Tools”-->“Go” (或按键盘F5)来运行一个脚本吧!注意在运行时上传窗口当前处于打开状态。

3、脚本运行正常,将其保存为upfile.au3,这里保存的脚本可以通过Run Script 工具将其打开运行,但我们的目的是希望这个脚本被Python程序调用,那么就需要将其生成exe程序。打开Compile Script to.exe工具,将其生成为exe可执行文件。如图5

图 5 Compile Script to.exe生成exe程序

点击“Browse”选择upfile.au3文件,点击“Convert”按钮将其生成为upfile.exe程序。

4、下面就是通过自动化测试脚本调用upfile.exe程序实现上传了。

#coding=utf-8
from selenium import webdriver
import os

driver = webdriver.Firefox()

#打开上传功能页面
file_path =  'file:///' + os.path.abspath('upfile.html')
driver.get(file_path)

#点击打开上传窗口
driver.find_element_by_name("file").click()
#调用upfile.exe上传程序
os.system("D:\\upfile.exe")

driver.quit()

通过Python 的os模块的system()方法可以调用exe程序并执行。

了解了上传的实现过程,那么下载也是一样的。

]]>
git 学习笔记 2014-07-07T00:00:00+00:00 Joyce http://minghongjun.github.io/git-学习笔记 安装git
git init
git remote add origin http://github.com/joyce/joyce.github.io.git
git pull origin master

安装插件

ctrl+~

输入:

import urllib2,os,hashlib; h = '7183a2d3e96f11eeadd761d777e62404' + 'e330c659d4bb41d3bdf022e94cab3cd0'; pf = 'Package Control.sublime-package'; ipp = sublime.installed_packages_path(); os.makedirs( ipp ) if not os.path.exists(ipp) else None; urllib2.install_opener( urllib2.build_opener( urllib2.ProxyHandler()) ); by = urllib2.urlopen( 'http://sublime.wbond.net/' + pf.replace(' ', '%20')).read(); dh = hashlib.sha256(by).hexdigest(); open( os.path.join( ipp, pf), 'wb' ).write(by) if dh == h else None; print('Error validating download (got %s instead of %s), please try manual install' % (dh, h) if dh != h else 'Please restart Sublime Text to finish installation')

https://sublime.wbond.net/installation#st2

git config --global user.name "joyce"

git config --global user.email "joyce@163.com"

push.sh:
git add .
git commit -a -m "daily updates"
git push origin master
]]>
Jenkins jenkins打包后自动部署 2014-07-07T00:00:00+00:00 Joyce http://minghongjun.github.io/Jenkins-打包后自动部署 Jenkins 打包后自动部署见下图:

tomcat用户配置:

<role rolename="tomcat" />  
<role rolename="admin"/>  
<role rolename="admin-gui"/>  
<role rolename="manager"/>  
<role rolename="manager-gui"/>  
<role rolename="manager-script"/>  
<user username="shanlin" password="tomcat" roles="tomcat,admin-gui,admin,manager,manager-gui,manager-script"/>  
]]>
重置mysql密码 2014-06-14T00:00:00+00:00 Joyce http://minghongjun.github.io/mysql-ruby
  • 重置mysql密码 http://www.php100.com/html/webkaifa/database/Mysql/2011/0624/8359.html
  • 代码

    > mysqld stop
    > mysqld --skip-grant-tables --skip-networking
    
    > mysql
    > UPDATE mysql.user SET Password=PASSWORD('newpass') WHERE User='root' AND Host='localhost';
    > FLUSH PRIVILEGES;
    
    > mysqld restart
    
    ]]>
    Redmine Windows下安装Redmine 2014-06-10T00:00:00+00:00 Joyce http://minghongjun.github.io/Redmine-Windows下安装Redmine 原文

    一、Redmine安装。

    1、准备

    安装之前请阅读:RailsInstaller简化了Rails在Windows上的安装过程

    英文原文:RailsInstaller Provides Easy Rails on Windows Installation

    RailsInstaller向Windows开发者提供了一种便捷的方式以轻松、快速创建Ruby on Rails 3应用。到目前为止,Windows开发者需要自己搭建好Ruby、RubyGems、Rails以及SQLite才能开始创建Rails应用。多亏了来自Engine Yard的Nic Williams博士及其团队,现在一切都变得简单异常。

    目前的RailsInstaller提供了如下功能:

    通过向导的轻松安装
    Rails 3.0.3
    Ruby 1.8.7——p330
    SLQite 3.7.3
    Git 1.7.3.1
    DevKit
    

    2、安装

    注意:下面的操作要在联网的情况下进行。

    转自:http://www.cppblog.com/giigie/archive/2011/07/31/152160.html

    最近在一家公司实习。公司用的项目管理软件是开源的redmine,体验非常不错。我想这个东西不仅可以用来管理项目,也可以用来管理个人的学习工作进展啊。于是,我也在自己的虚拟机的2003 server 下安装。

    之前为了安装wordpress,我已经在我的电脑上安装了 xampp。这是一个搭建服务器环境的傻瓜式安装包,里面集成了apache,php,mysql,phpMyAdmin,FileZilla FTP Server,Tomcat,这些组件可以选择安装。.

    因为redmine是需要apache 和mysql的,所以正好。此外,redmine使用ruby写的,所以还需要ruby的环境。

    配置ruby 的环境我选用的是railsinstaller 。

    之前我在网上搜索安装redmine 的教程,配置ruby环境大多是用InstantRails。我实际用了一下,效果不太好。因为InstantRails从2007年开始就没有更新了,里面包含的很多组件版本都很旧,直接搭建的话需要升级各种组件,而且组件之间的依赖关系比较混乱,反正我是在里面绕了很多弯路。而且InstantRails 里面自带有很低版本的apache,mysql,phpMyAdmin,如果你电脑本来安装了这些,那么又要改这些服务的端口和对应的配置文件。总之一句话,InstantRails 已经过时了。

    好了,现在开始进入正题吧。

    1.去redmine的官方网站下载 redmine 的最新版本。我下载的的是redmine 2.5.1然后弄清楚这个版本的需要的环境。Redmine 的网站的Guide » Installation Guide » 会清楚的告诉你这些事项的。

    2.如果你的电脑上还没有apache ,php,mysql 建议你去下载xampp,如果有的话,跳过这步。

    3.去railsinstaller 的官方网站去下载最新版的railsinstaller 。看它所包含的组件以及其版本。然后安装。

    4.做好这些准备工作了。就可以开始配置redmine运行环境了。把redmine的解压到railsinstaller所产生的sites目录。在dos窗口进入sites\redmine目录下。

    5.gem install rails -v=3.2.17 安装rails 3.2.17版本,这个redmine 2.5.1所要求的(可以根据提示安装正确的版本)。

    (PS:如果安装版本不正确,或者安装多个版本,可以用如gem uninstall rails来卸载)

    6.gem install rack -v=1.1.1 安装rack 1.1.1版本,这个redmine 1.2.1所要求的。

    7.gem install -v=0.4.2 i18n 这个根据安装时返回的错误命令提示来决定。比如的我就是提示Missing the i18n 0.4.2 gem. Please gem install -v=0.4.2 i18n

    8.进入phpMyAdmin 创建数据库。执行以下三条sql 语句。

    create database redmine character set utf8;

    create user 'redmine'@'localhost' identified by 'my_password';

    grant all privileges on redmine.* to 'redmine'@'localhost';

    9.拷贝config/database.yml.example文件到config/database.yml,修改database.yml的内容 production:

      adapter: mysql2
    
      database: redmine
    
      host: localhost
    
      username: redmine
    
      password: my_password
    

    Username 和password字段就是自己要设置的数据库的账号和密码。

    10.回到dos 窗口下,设置Session Key,执行 rake generate_session_store

    如果提示 mysql 错误,再执行如下语句 gem install mysql

    1. 如果提示有其它没有安装成功的语句,而且bundle install 安装报rmagick错误的话,在Windows下安装这个一直安装不成功,所以可以用bundle install --without development test rmagick 
    
    2. 如果电脑已经有mysql了,安装adapter:mysql2 要跟mysql关联:gem install mysql2 -- --with-mysql-dir=F:/shanlin/xampp/mysql
    
    3. 替换libmysql.dll文件,由于RailsInstaller中的mysql编译版本问题,我们需要下载<http://dev.mysql.com/get/Downloads/Connector-C/mysql-connector-c-noinstall-6.0.2-win32.zip/from/pick>,将解压后的 lib\libmysql.dll 文件拷贝到 C:\RailsInstaller\Ruby1.9.3\bin下;
    
    3.3. 3中的办法经常会报 Incorrect MySQL client library version! This gem was compiled for 5.6.16 but the client library is 6.0.0等类似的错误,解决办法:把已经安装好的mysql/lib下的libmysql.dll,libmysql.lib文件拷贝到C:\RailsInstaller\Ruby1.9.3\bin下;
    
    4. rake generate_session_store 如果提示这句语句过时,用其它语句代替的话就用其它语句代替
    

    11.然后set RAILS_ENV=production

    rake db:migrate

    rake redmine:load_default_data

    执行rake load_default_data RAILS_ENV="production" 完后,会提示Select language: bg, bs, ca, cs, da, de, el, en, en-GB, es, eu, fi, fr, gl, he, hr, hu, id, it, ja, ko, lt, lv, mn, nl,no, pl, pt, pt-BR, ro, ru, sk, sl, sr, sr-CY, sv, th, tr, uk, vi, zh, zh-TW [en] zh

    输入zh选择中文

    12.最后ruby script/server webrick -e production 启动。如果报没有这个模块,就用:rails server 代替 以后每次开机后都需要这句来启动。

    13.打开浏览器 输入 http://localhost:3000 。账号,密码都是 admin 。

    14.安装完了,就可以使用admin用户登录,密码也是admin,登入后,发现页面又变成了英文的,在这里要设置个人用户,修改语言为中文就可以了。然后进入管理页面,可以管理项目,用户,角色,权限,问题状态,跟踪类型,流程等。

    如果打开页面,终端报错:WARN Could not determine content-length of response body. Set content-length of the response or set Response#chunked = true

    解决办法 :

    找到ruby的安装路径:

    D:\Ruby193\lib\ruby\1.9.1\webrick\httpresponse.

    Ruby代码

    if chunked? || @header['content-length']   
    

    修改为:

    Ruby代码

    if chunked? || @header['content-length'] || @status == 304 || @status == 204  
    

    重启

    兼容性提示

    ruby1.9只能用adapter mysql2,不能用mysql

    ]]>
    Maven 常用操作和常见问题 2014-06-10T00:00:00+00:00 Joyce http://minghongjun.github.io/Maven-常用操作和常见问题 常见操作

    上传到maven资源库

    mvn deploy:deploy-file -DgroupId=com.chinapay -DartifactId=netpayclient -Dversion=1.0 -Dpackaging=jar -Dfile=D:\netpayclient-1.0.jar -Durl=http://192.16.220.232:8082/content/repositories/thirdparty/ -DrepositoryId=releases 
    

    常见问题

    pom.xml问题修复: Plugin execution not covered by lifecycle

    Problems and how to fix

    If you are using Eclipse together with m2eclipse on Windows, you may see errors on the pom.xml's of your created project that say: Description Resource Path Location Type

    Plugin execution not covered by lifecycle configuration: com.googlecode.mavenfilesync:maven-filesync-plugin:1.0.0:generate (execution: default, phase: initialize) pom.xml /myhippoproject-cms line 5 Maven Project Build Lifecycle Mapping Problem

    You can fix this as follows:

    1.open the 'Problems' view: 'Window' -> 'Show View' -> 'Problems'
    2.right-click on one of the red errors that say 'Plugin execution not covered by lifecycle configuration: com.googlecode.mavenfilesync:maven-filesync-plugin:1.0.0:generate (execution: default, phase: initialize)'
    3.from the menu, choose 'Quick Fix'
    4.in the Quick Fix dialog, select the fix 'Permanently mark goal generate in pom.xml as ignored in Eclipse build' and click 'Finish'. Select 'OK' in the next dialog to apply the fix to the 'cms' or 'site' pom. Do not use the root pom here.
    5.Repeat steps 2-4 for the other, identical error
    6.Eclipse will now show two new red errors: 'Projct configuration is not up-to-date with pom.xml. Run project configuration update'. Right-click on one of these errors and choose 'Quick Fix' again.
    7.The only suggested quick fix is 'Update project configuration'. Select all resources and click 'Finish'.
    

    The above steps actually add the following to the section of the files 'site/pom.xml' and 'cms/pom.xml':

    <</code>pluginManagement>
      <</code>plugins>
        <</code>plugin>
          <</code>groupId>org.eclipse.m2e</</code>groupId>
          <</code>artifactId>lifecycle-mapping</</code>artifactId>
          <</code>version>1.0.0</</code>version>
          <</code>configuration>
            <</code>lifecycleMappingMetadata>
              <</code>pluginExecutions>
                <</code>pluginExecution>
                  <</code>pluginExecutionFilter>
                    <</code>groupId>com.googlecode.mavenfilesync</</code>groupId>
                    <</code>artifactId>maven-filesync-plugin</</code>artifactId>
                    <</code>versionRange>[1.0.0,)</</code>versionRange>
                    <</code>goals>
                      <</code>goal>generate</</code>goal>
                    </</code>goals>
                  </</code>pluginExecutionFilter>
                  <</code>action>
                    <</code>ignore></</code>ignore>
                  </</code>action>
                </</code>pluginExecution>
              </</code>pluginExecutions>
            </</code>lifecycleMappingMetadata>
          </</code>configuration>
        </</code>plugin>
      </</code>plugins>
    </</code>pluginManagement> 
    
    ]]>
    Maven 使用maven ant task实现非标准打包 2014-06-10T00:00:00+00:00 Joyce http://minghongjun.github.io/Maven-使用maven-ant-task实现非标准打包 原文

    maven很强大,但是总有些事情干起来不是得心应手,没有使用ant时那种想怎么干就怎么干的流畅感。尤其当要打包一个特殊(相对maven的标准架构而且)时,常有不知所措的感觉。当然这个应该和自己对maven的了解不够有关,毕竟,“初学maven”嘛。

    但是maven在依赖管理方面实在是太强大了,太喜欢,退回原来的ant方式完全不可能,我想用过maven的人,一般是不会有回到原来在cvs,subversion中checkin/checkout n个jar包的时代,仅此一项理由就足够继续坚持使用maven了。

    然而ant的灵活又难于忘怀,尤其是从ant的build.xml一路走来的人,总是回不知不觉间想到ant的美好。鱼与熊掌,我都想要。最近想打包一个java应用,很简单但即不是标准的j2ee appication也不是web application, 用maven完全不知道该怎么打包,package出来的完全不是我想要的,在网上四处google maven资料的时候,总有用回ant拉倒的冲动。

    先交代一下背景吧,我要打包的程序,是这个样子:

    demo1
     |____lib
     |_____demo1.jar
     |_____*****.jar
     |_____*****.jar
     |____config
     |_____*****.properties
     |_____*****.xml
     |____log
     |_____*****.log
     |____run.bat
     |____run.sh
    

    这个应用的打包模式很简单,一个bat或者sh脚本用来执行,lib目录下存放所有的jar包,包括自己的源代码编译打包的jar和第三方包。config下是配置文件,这些文件需要在安装时或者运行前修改,比如监听的端口啊,数据库信息之类的。log目录存放日志文件。最后打包的产物是一个zip包(或者tar,tar.gz)。

    遇到的问题,就是maven标准的打包方式中根本不考虑类似的情况,什么jar,ear,war完全不适用。而且maven有些理念也诧异,比如maven标准的config目录是src/main/config,但是这个目录里面的配置文件默认会打包到jar包中,晕,都在jar里面了还让人怎么改啊?

    本着尽量只用maven不用ant的想法,我在maven的资料中看了好久,没有找到解决的方法。晕,难道大家都只打包标准的ear,jar,war,只有我这样无聊的人才会有这种打包的需求?

    几经寻觅和探索,最后发现,maven ant tasks似乎是一个不错的选择。带着mavenanttasks的官方文档和google上搜到的几篇文章,开始尝试,成功实现功能。现在将过程和方法share给大家。

    首先建立java项目anttaskdemo1,按照maven的推荐,文件结构如下:

    anttaskdemo1
     |____src/main/java
     |____src/main/config
     |____src/main/bin
     |____src/main/resources
     |____src/test/java
     |____src/test/resources
     |____target
     |____build.properties
     |____build.xml
     |____pom.xml
    

    其中src/main/java下放java代码;src/main/resources下放一个*.properties文件,这个资源文件是打包到jar中,内容打包之后不需要改变的。src/main/config下放一个标准的log4j.xml,这个是有在安装运行前临时修改的需要的。src/main/bin下放置可执行文件。

    1.首先看pom.xml,标准内容,很简单,象征性的加入几个依赖

    <dependency>
     <groupId>commons-codec</groupId>
     <artifactId>commons-codec</artifactId>
     <version>1.3</version>
    </dependency>
    <dependency>
     <groupId>log4j</groupId>
     <artifactId>log4j</artifactId>
     <version>1.2.13</version>
     <scope>compile</scope>
    </dependency>
    <dependency>
     <groupId>org.testng</groupId>
     <artifactId>testng</artifactId>
     <version>5.8</version>
     <scope>test</scope>
     <classifier>jdk15</classifier>
    </dependency>

    其中commons-codec,log4j是需要打包到lib中的,运行时需要。testng(或者更一般的junit)是用来单元测试的,不需要打包到lib中。请注意它的设置"test"。

    2.然后看看build.properties文件,这个内容不多:

    M2_REPO=G:/soft/maven/localRepository
    
    path.package=package
    path.target.name=anttaskdemo1
    path.package.lib=lib
    path.package.log=log
    path.package.config=config
    path.package.bin=
    
    
     M2_REPO稍后再详谈,后面的path.package之类的是最终打包时使用的几个目录名称,对应于最终打包的结构。
    

    3.build.xml,这个内容比较多。

    <?xml version="1.0" encoding="UTF-8"?>
    <project name="demo" default="all" xmlns:artifact="urn:maven-artifact-ant">
         <description>
         </description>
         <property file="build.properties" />
         <target name="init_maven">
             <!--
            remember to set M2_REPO before use this build.xml, for example in eclispe:
             "Window→Preferences→Ant→Runtime", add a new property named "M2_REPO" and set it value point to the path of your maven
             local repository; Or you can set it in build.properties.  You need do one (and only one) of them.
             -->
             <path id="maven-ant-tasks.classpath" path="${M2_REPO}/org/apache/maven/maven-ant-tasks/2.0.9/maven-ant-tasks-2.0.9.jar" />
             <typedef resource="org/apache/maven/artifact/ant/antlib.xml" uri="urn:maven-artifact-ant" classpathref="maven-ant-tasks.classpath" />
             <artifact:pom id="maven.project" file="pom.xml" />
             <artifact:dependencies pathId="classpath.build" filesetid="maven.fileset.build">
                 <pom refid="maven.project" />
             </artifact:dependencies>
             <artifact:dependencies pathId="classpath.runtime" filesetid="maven.fileset.runtime" useScope="runtime">
                 <pom refid="maven.project" />
             </artifact:dependencies>
         </target>
         <target name="all" depends="init_path, compile, jar, package, zip" description="do all">
             <echo>begin to do all target to build the result package.</echo>
         </target>
         <target name="maven_info" depends="init_maven">
             <echo>Maven build directory is ${maven.project.build.directory}</echo>
             <echo>Maven build finalName is ${maven.project.build.finalName}</echo>
             <echo>Maven build sourceDirectory directory is ${maven.project.build.sourceDirectory}</echo>
             <echo>Maven build outputDirectory directory is ${maven.project.build.outputDirectory}</echo>
             <echo>Maven build scriptSourceDirectory directory is ${maven.project.build.testSourceDirectory}</echo>
             <echo>Maven build testOutputDirectory directory is ${maven.project.build.testOutputDirectory}</echo>
             <echo>Maven build scriptSourceDirectory directory is ${maven.project.build.scriptSourceDirectory}</echo>
             <echo>Maven build resourceDirectory directory is ${maven.project.build.resources}</echo>
             <property name="target.jar.name" value="${maven.project.build.directory}/${maven.project.build.finalName}.jar" />
             <echo>Maven build scriptSourceDirectory directory is ${target.jar.name}</echo>
         </target>
         <target name="clean" depends="init_maven">
             <echo>clean build directory : ${maven.project.build.directory}</echo>
             <delete dir="${maven.project.build.directory}" includes="**/*" />
         </target>
         <target name="init_path" depends="maven_info, clean">
             <echo>make dir for java compile: ${maven.project.build.outputDirectory}</echo>
             <mkdir dir="${maven.project.build.outputDirectory}" />
         </target>
         <target name="compile" description="description" depends="init_maven">
             <javac srcdir="${maven.project.build.sourceDirectory}" destdir="${maven.project.build.outputDirectory}" classpathref="classpath.build" />
         </target>
         <target name="copyResource" depends="init_maven">
             <copy todir="${maven.project.build.outputDirectory}">
                 <fileset dir="src/main/resources">
                 </fileset>
             </copy>
         </target>
         <target name="jar" depends="compile, copyResource">
             <delete file="${maven.project.build.directory}/${maven.project.build.finalName}.jar"  failonerror="false" />
             <jar destfile="${maven.project.build.directory}/${maven.project.build.finalName}.jar" basedir="${maven.project.build.outputDirectory}">
             </jar>
         </target>
         <target name="package" depends="package_prepare, copyLib, copyConfig, copyBin">
         </target>
         <target name="package_prepare" depends="init_maven">
             <echo>clean package directory : ${maven.project.build.directory}/${path.package}</echo>
             <delete dir="${maven.project.build.directory}/${path.package}" />
             <mkdir dir="${maven.project.build.directory}/${path.package}" />
             <mkdir dir="${maven.project.build.directory}/${path.package}/${path.target.name}" />
             <mkdir dir="${maven.project.build.directory}/${path.package}/${path.target.name}/${path.package.lib}" />
             <mkdir dir="${maven.project.build.directory}/${path.package}/${path.target.name}/${path.package.config}" />
             <mkdir dir="${maven.project.build.directory}/${path.package}/${path.target.name}/${path.package.log}" />
         </target>
         <target name="copyLib" depends="init_maven">
             <copy todir="${maven.project.build.directory}/${path.package}/${path.target.name}/${path.package.lib}">
                 <fileset refid="maven.fileset.runtime" />
                 <mapper type="flatten" />
             </copy>
             <copy todir="${maven.project.build.directory}/${path.package}/${path.target.name}/${path.package.lib}"
                 file="${maven.project.build.directory}/${maven.project.build.finalName}.jar">
             </copy>
         </target>
         <target name="copyConfig" depends="init_maven">
             <copy todir="${maven.project.build.directory}/${path.package}/${path.target.name}/${path.package.config}">
                 <fileset dir="src/main/config">
                 </fileset>
             </copy>
         </target>
         <target name="copyBin" depends="init_maven">
             <copy todir="${maven.project.build.directory}/${path.package}/${path.target.name}/${path.package.bin}">
                 <fileset dir="src/main/bin">
                 </fileset>
             </copy>
         </target>
         <target name="zip" depends="init_maven">
             <zip destfile="${maven.project.build.directory}/${path.package}/${path.target.name}.zip">
                 <fileset dir="${maven.project.build.directory}/${path.package}/${path.target.name}"></fileset>
             </zip>
         </target>
    </project>

    一步一步来讲吧:

    3.1 最重要的一步,init_maven

    <target name="init_maven">
         <!--
        remember to set M2_REPO before use this build.xml, for example in eclispe:
         "Window→Preferences→Ant→Runtime", add a new property named "M2_REPO" and set it value point to the path of your maven
         local repository; Or you can set it in build.properties.  You need do one (and only one) of them.
         -->
         <path id="maven-ant-tasks.classpath" path="${M2_REPO}/org/apache/maven/maven-ant-tasks/2.0.9/maven-ant-tasks-2.0.9.jar" />
         <typedef resource="org/apache/maven/artifact/ant/antlib.xml" uri="urn:maven-artifact-ant" classpathref="maven-ant-tasks.classpath" />
         <artifact:pom id="maven.project" file="pom.xml" />
         <artifact:dependencies pathId="classpath.build" filesetid="maven.fileset.build">
             <pom refid="maven.project" />
         </artifact:dependencies>
         <artifact:dependencies pathId="classpath.runtime" filesetid="maven.fileset.runtime" useScope="runtime">
             <pom refid="maven.project" />
         </artifact:dependencies>
    </target>

    在ant中使用maven-ant-tasks,就需要装载maven-ant-tasks的jar包,方法有两种,一种是直接将maven-ant-tasks-2.0.9.jar放到ant的lib下,自然就可以直接使用。但是个人感觉不怎么喜欢这种方式,我采用的是第二种,在ant的build.xml文件中装载:

    <path id="maven-ant-tasks.classpath" path="${M2_REPO}/org/apache/maven/maven-ant-tasks/2.0.9/maven-ant-tasks-2.0.9.jar" />
    <typedef resource="org/apache/maven/artifact/ant/antlib.xml" uri="urn:maven-artifact-ant" classpathref="maven-ant-tasks.classpath" />

    这样就可以在后面使用maven-ant-tasks的task,比如artifact:pom,artifact:dependencies。用于指定maven-ant-tasks-2.0.9.jar的路径,这里就有点麻烦了:maven-ant-tasks-2.0.9.jar这个东西放哪里好呢?直接放到项目中,然后存放到cvs/svn?显然不是一个好办法。考虑到maven本来就是干保存jar这行的,交给maven好了。maven-ant-tasks-2.0.9.jar本来就是一个依赖,可以在http://mvnrepository.com/找到:

    http://mvnrepository.com/artifact/org.apache.maven/maven-ant-tasks

    pom内容如下:

    <dependency>
     <groupId>org.apache.maven</groupId>
     <artifactId>maven-ant-tasks</artifactId>
     <version>2.0.9</version>
    </dependency>

    将这个内容随便找个空项目,加入后update一下dependency,在本地的maven repository中就会有它的jar文件。然后就可以直接使用它。

    ${M2_REPO},这个是eclipse中通用的指向maven local repository的变量,大家使用maven命令建立eclipse项目时会遇到它。我们在这里可以直接使用这个变量来访问maven local repository。如果没有建立这个变量,请自行建立,上面注释中有详细说明。如果在eclispe之外比如命令行直接运行ant打包,则可以通过设置build.properties文件中的“M2_REPO=G:/soft/maven/localRepository”来指定。(这里用到ant的一个特性,属性一旦被赋值就不能修改,因此第一次赋值有效,在eclispe中运行,M2_REPO会使用eclispe中设置的值,如果eclispe没有设置或者命令行直接运行,M2_REPO属性会在build.properties文件装载时设置。)

    装载ok后,接着是调用artifact:pom和artifact:dependencies 任务来指定pom.xml文件,再得到dependencies信息,后面的编译打包会使用到。注意useScope="runtime",这个是为了最后打包时使用,只复制runtie时需要的jar包。

    是用来打印maven相关的一些信息的,比如maven下的几个build目录。artifact:pom任务装载了整个pom,因此在后面可以访问到pom的信息,比如${maven.project.build.sourceDirectory}是java源代码目录,${maven.project.build.finalName}是最终的名称。

    pom的内容可以参考这两个官方资料:

    1) maven model

    http://maven.apache.org/ref/2.0.9/maven-model/maven.html

    2) Introduction to the POM

    http://maven.apache.org/guides/introduction/introduction-to-the-pom.html

    标准目录布局可以参考这个官方资料:

    http://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html

    3.2 compile

    这里是maven ant task的精髓所在,

    <target name="compile" description="description" depends="init_maven">
         <javac srcdir="${maven.project.build.sourceDirectory}" destdir="${maven.project.build.outputDirectory}" classpathref="classpath.build" />
     </target>

    结合之前maven初始化时的情况:

    <artifact:pom id="maven.project" file="pom.xml" />
     <artifact:dependencies pathId="classpath.build" filesetid="maven.fileset.build">
         <pom refid="maven.project" />
     </artifact:dependencies>

    可以看到,我们的项目完全遵循maven的标准做法,然后ant通过访问pom来得到相关的路径信息和classpath信息,完美结合。

    target copyResource 完成了将resource copy到outputDirectory的任务,这里的resource都是classpath resource。

    注: 这个有个问题,就是我没有找到通过pom得到resouce目录的方法,${maven.project.build.resources 只能得到pom文件中, 对于里面包含的不知道该用什么方式来访问,如默认的:

    <resources>
       <resource>
         <directory>src/main/resources</directory>
       </resource>
     </resources>

    我试过用${maven.project.build.resources[0];${maven.project.build.resources(0), ${maven.project.build.resources.0,${maven.project.build.resources.resource 等都无效。找了很久都没有找到资料,只好作罢。直接写死src/main/resources吧。

    3.3 jar

    和compile类似,标准的ant jar,然后通过访问pom来得到相关的路径信息和打包文件名。注意这里的文件名和路径和maven的做法一致,也就是说和执行maven的compile命令结果是一样的。

    <target name="jar" depends="compile, copyResource">
         <delete file="${maven.project.build.directory}/${maven.project.build.finalName}.jar"  failonerror="false" />
         <jar destfile="${maven.project.build.directory}/${maven.project.build.finalName}.jar" basedir="${maven.project.build.outputDirectory}">
         </jar>
     </target>

    3.4 package, zip

    package_prepare, copyLib, copyConfig, copyBin 这几个target都简单,体力活而已。zip也是。

    1. 总结

    上面的内容虽多,但是总结起来就只有两点:

    1. maven ant task可以将maven的功能和ant的灵活性统一起来,对于非标准的打包情况非常适用

    2. maven ant task的使用并不难,不过需要掌握不少maven的基本知识,比如pom,标准目录布局等。

    另外,似乎,ant + Ivy会是更好的选择?

    ]]>
    linux 常见问题 2014-06-10T00:00:00+00:00 Joyce http://minghongjun.github.io/Linux-常见问题 ubuntu:file system check failed

    关于ubuntu突然停电后提示file system check failed不能进入系统的解决办法

    以前遇到为类似问题都是重装系统解决问题。今天我特意把电源突然拔掉,来试验解决办法,

    经试验,已经成功,

    分享如下:

    1,症状

    不能进入系统,提示file system check failed[failed]

    2,解决办法

    在输入终端命令:fsck。

    在提示符下一路点yes。

    重启机器。

    问题解决。

    3,存在的问题

    进入 系统后软件的设置都成原始状态。比如Foxfire

    ubuntu常见一些问题

    1、从桌面版怎么能进命令模式呢?

    alt + ctrl + f1 ~ f6

    或者

    在终端中输入命令:sudo /etc/init.d/gdm stop 进入文本模式

    alt + ctrl + f7 ~ f12

    或者

    startx 回到桌面

    2、为什么用sudo /etc/init.d/gdm stop进入命令行界面后,再以startx进入图形界面的话这个命令sudo /etc/init.d/gdm stop就再也不行了呢?

    需要搞清楚系统服务GDM(/etc/init.d/gdm)和X-Window的关系。

    gdm服务是一个脚本,通过这个脚本可以启动X-Window并将gdm程序(/usr/bin/gdm) 作为窗口管理器 (Desktop Manager)。

    系统服务的状态通常有两种:Running 或者 Stopped, 其状态转换可以通过下面的命令实现: Stopped ==> Running: /etc/init.d/xxx start (开启服务) Running ==> Stopped: /etc/init.d/xxx stop (停止服务) 还有另外一种: /etc/init.d/xxx restart (重启服务)

    前面使用 /etc/init.d/gdm stop 来将服务关闭了(同时也关闭了已经打开的 X-window),然后用 startx 来启动了 X-window, 此时 gdm服务已经停止,你再次使用 /etc/init.d/gdm stop 的话,由于该服务已经停止,这个命令当然不会有什么作用。

    记住: 系统服务只能在已经启动的前提下才能关闭或者重启,所以说“只能用一次这个命令”。

    ]]>
    linux Ubuntu 安装 Postgresql Pgadmin 2014-06-10T00:00:00+00:00 Joyce http://minghongjun.github.io/Linux-Ubuntu安装Postgresql-Pgadmin 第一步:在Ubuntu下安装Postgresql

    sudo apt-get install postgresql

    以上指令安装服务端和命令行客户端psql。

    /usr/lib/postgresql/8.4/              存放postgresql相关的二进制文件
    /usr/lib/postgresql/8.4/bin/        可执行文件
    /usr/lib/postgresql/8.4/lib/         共享库文件
    /etc/postgres/8.4/main/              存放postgresql配置文文件
    /var/lib/postgresql/                    postgres用户的主文件夹
    

    第二步:修改PostgreSQL数据库的默认用户postgres的密码

    PostgreSQL数据默认会创建一个postgres的帐号用户作为数据库的管理员,密码是随机的,所以:

    首先,我们需要重置“postgres”用户的密码。

    命令行如下:

    sudo -u postgres psql(或者sudo su postgres -c psql)—>运行psql,psql是一个标准的postgressql客户端 postgres=# ALTER USER postgres WITH PASSWORD ‘postgres’;—>修改postgres的密码为postgres,不要忘记添加分号(回车后分号之前的sql语句才会立即执行) postgres=# \q—>退出

    修改了数据库中的密码之后,我们还需要修改linux下的用户“postgres”的密码:设定成与数据库中postgres帐号相同的密码,即postgres。

    sudo passwd -d postgres———>删除密码

    sudo -u postgres passwd(或者 sudo su postgres -c passwd)—–>创建密码

    然后输入跟之前一样的密码。

    现在,我们就可以在数据库服务器上用 postgres帐号通过psql或者pgAdmin等等客户端操作数据库了(暂时还不能远程访问)。

    第三步:修改PostgresSQL数据库配置实现远程访问

    首先,我们需要编辑postgresql.conf:

    sudo gedit /etc/postgresql/8.4/main/postgresql.conf

    现在,我们需要修改“连接和权 限”两行。

    改变行:#listen_addresses = ‘localhost’ 修改为:listen_addresses = ‘*’

    改变行:#password_encryption = on 修改为:password_encryption = on

    保存并关闭gedit。

    最后一步,我们必须设置谁才可以操作数据服务器,这一切都是在pg_hba.conf中完成的。

    sudo gedit /etc/postgresql/8.4/main/pg_hba.conf

    把以下内容添加到 pg_hba.conf底部:

    # to allow your client visiting postgresql server
    

    host all all 0.0.0.0 0.0.0.0 md5

    解释一下最后一行:

    host表示允许的类型是主机;

    第一个all是允许的数据库名字;

    第二个all是允许的用户;

    第一个0.0.0.0是允许访问的ip address;

    第二个0.0.0.0是允许访问的subnet mask;

    最后的md5表示密码的加密方式,如果将md5改成trust则可以让指定范围的主机数据库的时候不需要提供密码。

    关于ip address和subnet mask,你也可以修改为你的机器IP地址(如10.13.19.53)和子网掩码(如 255.255.255.255),这样就只有你自己的主机可以远程访问数据库了。

    如果要使用一个IP地址范围,只需要把子网掩码设置成合适的值,如果子网掩码设置成0.0.0.0,则所有主机均可以访问数据库(IP可以任意设定),如 果将md5改成trust则可以让指定范围的主机访问指定的数据库的时候不需要提供密码。

    重启服务器,以上的配置就生效了:sudo /etc/init.d/postgresql-8.4 restart

    第四步:创建用户和数据库。

    使用命令行创建用户和数据库:

    sudo -u postgres createuser -D -P mynewuser—->-D该用户没有创建数据库的权利,-P提示输入密码,后面的选项都可以省略,命令执行的时候会提示用户选择yes或者no sudo -u postgres createdb -O mynewuser mydatabase—>-O设定所有者为mynewuser 或者使用psql创建用户和数据库:

    首先利用psql登录postgresql服务器:sudo -u postgres psql[ -U postgres -h 127.0.0.1]—->运行psql,后面[]中的内容可选,用于登录服务器,默认会登录本机;

    然后在psql程序中创建用户和数据库:用户名和数据库名称加上引号后才区分大小写,否则会自动转换成小写:

    create user “mynewuser” with password ‘mynewuser nocreatedb;

    create database “mydatabase” with owner=mynewuser;

    第五步:如何安装和使用pgAdmin3客户端操作postgresql数据库

    首先安装图形客户端pgAdmin3,安装命令行:sudo apt-get install pgadmin3 然后运行客户端并连接数据库,直接上图:

    如果要让别人访问你的postgres:

    在pg_hba.conf中(这个文件在pgAdmin的data目录下):

    sudo gedit /etc/postgresql/8.4/main/pg_hba.conf

    把以下内容添加到 pg_hba.conf底部:

    # to allow your client visiting postgresql server
    

    host all all 0.0.0.0 0.0.0.0 md5

    注意如果是Window7的话,要先把Window7的防火墙关掉,不然还是不能访问!!!

    另:修改PgAdmin的密码:

    文件-->更改密码

    ]]>