分类: 默认

  • bytedeco opencv在gradle中无法使用的问题

    bytedeco opencv是一个opencv的封装,所有依赖都可以在maven中央库中找到,是一个非常方便的东西。

    如果你是用构建工具,那么只需要引入

     <dependency>
        <groupId>org.bytedeco</groupId>
        <artifactId>javacv</artifactId>
        <version>1.2</version>
      </dependency>

    就应该可以正常使用。

    因为opencv对于不同平台需要不同平台对应的编译,所以构建项目的时候会去下载对应的编译依赖,如果你使用gradle就会遇到这种问题

    Could not resolve all dependencies for configuration ':compileClasspath'.
    > Could not find javacpp-presets-Windows 8.1-amd64.jar (org.bytedeco:javacpp-presets:1.2).
      Searched in the following locations:
          https://repo1.maven.org/maven2/org/bytedeco/javacpp-presets/1.2/javacpp-presets-1.2-Windows 8.1-amd64.jar
    

    去仓库看看,的确没有这个文件。但是这种方式在maven中工作。

    那是因为默认的解析规则是javacpp-presets-${os.name}-${os.arch}.jar,而maven和gradle中的解析有一些不同之处,所以最简单的处理办法是自己手动引入对应的编译依赖

    compile group: 'org.bytedeco.javacpp-presets', name: 'opencv', version: 
  • 自定义Jackson Serializer实现复杂Json转换

    Jackson绝对是一个方便好用的工具,可以快速的在json和java object之间转换。Spring中也集成了Jackson,所以可以方便的自动赋予这个特性,比如使用restOperations消费API的时候。

    但是有时候要消费的API要求的json很诡异,比如创建新用户,对方要求的格式如下:

    {
    	"data": {
    		"attrs": {
    			"firstName": "FN",
    			"lastName": "LN"
    		},
    		"dateOfBirth": {
    			"detail": "1900-01-01"
    		}
    	}
    }

    如果直接使用,那么我们的类对象就有点复杂了,需要嵌套好几层。但是我们也清楚,业务需要的不过就是三个数据而已,姓;名;生日。

    这个时候就可以考虑自定义Serializer了。

    比如这样

    class CustomerSerializer extends JsonSerializer<Customer> {
        @Override
        public void serialize(Customer value, JsonGenerator gen, SerializerProvider provider) throws IOException {
            
  • Spring中RestOperations的错误处理

    Spring提供了RestOperations来方便支持rest api的使用。不仅对于常用的方法语义有支持,对于常用的错误处理也有考虑,简单来说,用起来方便顺手,如果是返回json等常见格式,也能自动转为Java对象。

    RestOperations的默认错误处理由DefaultResponseErrorHandler负责,其中的方法hasError的返回值决定了是否将当前返回作为错误来对待。默认的实现是

    protected boolean hasError(HttpStatus statusCode) {
    		return (statusCode.series() == HttpStatus.Series.CLIENT_ERROR ||
    				statusCode.series() == HttpStatus.Series.SERVER_ERROR);
    	}

    也就是说4和5开头的状态码看作错误。然后在直接将返回内容封装一下抛出

    @Override
    	public void handleError(ClientHttpResponse response) throws IOException {
    		HttpStatus statusCode = getHttpStatusCode(response);
    		switch (statusCode.series()) {
    			case CLIENT_ERROR:
    				throw new HttpClientErrorException(statusCode, response.getStatusText(),
    						response.getHeaders(), 
  • 谈Gradle多项目工程的初始化

    Gradle可谓java世界最流行的依赖管理和构建工具。

    在安装了Java环境的情况再搭配Gradle Init Script工具我们可以很快初始化一个项目。比如

    $ gradle init --type java-library
    :wrapper
    :init
    
    BUILD SUCCESSFUL
    
    Total time: 3.551 secs

    这样初始化出来的项目包含了基本的配置和src目录,依赖默认有两个

    dependencies {
        compile 'org.slf4j:slf4j-api:1.7.5'
        testCompile 'junit:junit:4.11'
    }

    对于简单的工程而言这样就足够了,方便快捷。但是如果是一个多项目工程就创建不出来了。

    从目前Gradle官方的roadmap来说,init模块是会被废弃的,而且之后还会新增不同的工程类型,所以之后可能会增加对于多项目工程的支持,但是目前没有。

    所以目前来说简单的办法如下

    1. 建立basic项目
    2. 创建子项目的目录
    3. 进入子项目目录,创建java-library项目
    4. 删除所有子项目中的gradle相关文件
    5. 修改basic项目的settings.gradle,include所有子项目

    这样操作虽然很繁琐,但是可以很流畅的工作。

    这样创建出来的多项目工程的依赖管理全部依赖于主项目的build.gradle文件,也就是类似这样的写法

    project("spring-context") {
    	description = "Spring 
  • 为wordpress加上Redis

    wordpress随着文章数量增加,有时候访问稍微有一些就变得很慢了。

    今天有空就决定给wordpress加上Redis缓存。

    首先在Docker-compose中加上Redis依赖

    redis:
      image: redis:alpine

    然后link到wordpress中

    links:
    - redis

    然后安装Redis Object Cache,并在wp-config.php中把host改成redis,然后连接即可。

    redis-cache

  • 阿里云ubuntu系统升级到16.04

    之前一直使用的是阿里云上ubuntu 12.04系统,为了使用docker方便有过一次升级,不过那个时候升级比较粗暴,我直接更新了源,然后用apt-get upgrade升的级。

    今天想升级到16.04才突然发现了doreleaseupgrade,整个过程轻松加愉快。

    直接运行

    sudo do-release-upgrade -d

    升级之后检查一下

    lsb_release -a

    upgrade-ubuntu

  • Nginx配置所有访问导向同一页面

    最近由于各种原因,需要将之前的一个网站关闭。

    关闭之后因为域名没有到期,所以还是希望能够有一个静态页面让平时的常客至少下载一下存档,所以就做了一个静态网站。

    因为静态网站只有一个页面和一个zip存档,所以需要在nginx中将所有请求都转发到这个页面上。

    配置如下:

    location / {
        try_files $uri /index.html;
    }

    这样的话默认请求存在的文件的时候就会直接访问这些文件,否则就会跳转回首页。…

  • 使用Rultor简化开发

    通常一个项目,特别是开源项目有很多常见的操作,比如merge一个pull request或者发布一个版本。

    merge一个pull request可以通过github的issue页面完成,但是发布版本通常需要一些准备,特别是证书等等。

    Rultor是一个辅助工具,可以完成合并,发布等功能。

    Rultor的配置是.rultor.yml,这是一个例子

    decrypt:
      settings.xml: "repo/settings.xml.asc"
      pubring.gpg: "repo/pubring.gpg.asc"
      secring.gpg: "repo/secring.gpg.asc"
    docker:
      image: "yegor256/java8" 
    release:
      script: |
        mvn versions:set "-DnewVersion=${tag}"
        git commit -am "${tag}"
        mvn clean deploy -P central-deploy --settings /home/r/settings.xml -P cxf-spring-boot-starter-maven-plugin

    使用的时候很简单,比如需要发布新版本,直接创建一个issue,在其中@tultor即可

    @rultor release, tag is 
  • 使用Jenkins Groovy脚本添加Slave

    Jenkins应该是最常用的CI/CD工具了,而Jenkins也有官方的Docker版本,可以很方便的获得一个可用的Jenkins。

    但是大部分时候我们期待的是从Docker启动Jenkins之后一切环境都是准备就绪的,比如对应的插件啥的。

    对于插件来说还比较简单,直接提供一个plugin.txt文件即可

    credentials:1.18
    maven-plugin:2.7.1
    

    Jenkins的任务是可以在master直接运行的,但是很多时候,特别会需要很多不同构建环境的时候我们就会需要多个不同的Jenkins Slave了。

    Docker-Compose可以做到启动多个容器,这样我们就可以直接在其中就行配置了,比如一个java7的Slave,一个java8的,再来一个node的,但是最后还是需要到jenkins中添加这些Slave。

    Jenkins提供了Groovy脚本来实现一些配置和功能,比如需要修改执行器数量(默认为2),可以使用一些

    import jenkins.model.*
    Jenkins.instance.setNumExecutors(5)

    对于添加Slave的脚本就稍微复杂一些,需要用到import hudson.plugins.sshslaves.*

    大概的脚本如下

    List<Entry> env = new ArrayList<Entry>();
      EnvironmentVariablesNodeProperty envPro = new EnvironmentVariablesNodeProperty(env);
      Slave slave = new DumbSlave(
                        "java-7-node","",
                        "/var/jenkins_home",
                        "1",
                        Node.Mode.NORMAL,
                        "agent-node-label",
                        new SSHLauncher("java-7-node",22,"jenkins","password","","","","",""),
                        new RetentionStrategy.Always(),
                        new 
  • Apt的mirrors模式

    之前用的ubuntu一直配置的上海交通大学的源,速度也不错,最近升级到16.04以后又准备继续使用,突然发现可以直接使用mirrors自动选择最合适的源。

    默认的可用的列表文件在这里 http://mirrors.ubuntu.com/mirrors.txt

    在source.list直接使用

    deb mirror://mirrors.ubuntu.com/mirrors.txt xenial main restricted universe multiverse
    deb mirror://mirrors.ubuntu.com/mirrors.txt xenial-updates main restricted universe multiverse
    deb mirror://mirrors.ubuntu.com/mirrors.txt xenial-backports main restricted universe multiverse
    deb mirror://mirrors.ubuntu.com/mirrors.txt xenial-security main restricted universe multiverse