Kohei Nozaki's blog 

How to install a Eclipse project to local repository


Posted on Sunday Feb 23, 2014 at 04:51PM in Technology


Environment

  • Apache Maven 3.1.1
  • Eclipse Kepler SR1
  • Oracle JDK7u51
  • OS X 10.9.1

Why need to do it?

  • Many kind of dependency resolving work can take on Maven.
  • It is a better way than that take it on Eclipse or IDEs.
    • It is stable and it has some efficient mechanism like local repository.
    • We can just put in Jenkins job or shell scripts.
    • It makes automation of some annoying works (e.g. build, deploy, etc) much easier.
  • Thus, in this post, I'm going to try to resolve a dependency through local repository of Maven.

Create a project

  • I'm going to install this project to local repository.
  • After install, I will try to resolve a dependency to it from another project.

Create a project

  • Create a maven project named “hogeproject” in Eclipse.
    • Check “Create a simple project (skip archetype selection)”

Edit pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.nailedtothex</groupId>
    <artifactId>hogeproject</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <properties>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
</project>

Make a class

package hogeproject;

public class Hello {

    public String hello() {
        return "hello from hogeproject";
    }
}

Install the project to Maven repository

kyle-no-MacBook:hogeproject kyle$ pwd
/Users/kyle/Documents/workspace/hogeproject
kyle-no-MacBook:hogeproject kyle$ ls -l
total 8
-rw-r--r--+ 1 kyle  staff  566  2 23 17:07 pom.xml
drwxr-xr-x+ 4 kyle  staff  136  2 23 17:01 src
drwxr-xr-x+ 7 kyle  staff  238  2 23 17:12 target
kyle-no-MacBook:hogeproject kyle$ mvn install
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building hogeproject 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ hogeproject ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 0 resource
[INFO] 
[INFO] --- maven-compiler-plugin:2.5.1:compile (default-compile) @ hogeproject ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ hogeproject ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 0 resource
[INFO] 
[INFO] --- maven-compiler-plugin:2.5.1:testCompile (default-testCompile) @ hogeproject ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ hogeproject ---
[INFO] 
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ hogeproject ---
[INFO] 
[INFO] --- maven-install-plugin:2.4:install (default-install) @ hogeproject ---
Downloading: http://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-utils/3.0.5/plexus-utils-3.0.5.pom
Downloaded: http://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-utils/3.0.5/plexus-utils-3.0.5.pom (3 KB at 2.3 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-utils/3.0.5/plexus-utils-3.0.5.jar
Downloaded: http://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-utils/3.0.5/plexus-utils-3.0.5.jar (226 KB at 193.3 KB/sec)
[INFO] Installing /Users/kyle/Documents/workspace/hogeproject/target/hogeproject-0.0.1-SNAPSHOT.jar to /Users/kyle/.m2/repository/org/nailedtothex/hogeproject/0.0.1-SNAPSHOT/hogeproject-0.0.1-SNAPSHOT.jar
[INFO] Installing /Users/kyle/Documents/workspace/hogeproject/pom.xml to /Users/kyle/.m2/repository/org/nailedtothex/hogeproject/0.0.1-SNAPSHOT/hogeproject-0.0.1-SNAPSHOT.pom
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.438s
[INFO] Finished at: Sun Feb 23 17:19:25 JST 2014
[INFO] Final Memory: 11M/245M
[INFO] ------------------------------------------------------------------------
kyle-no-MacBook:hogeproject kyle$ 
  • It showed that the jar file and pom.xml were placed somewhere under $HOME/.m2/repository.

Create an another project

  • Create in Eclipse same way as above. Name is “higeproject”

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.nailedtothex</groupId>
    <artifactId>higeproject</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>
    <properties>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <failOnMissingWebXml>false</failOnMissingWebXml>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.nailedtothex</groupId>
            <artifactId>hogeproject</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>
</project>
  • A dependency to hogeproject is specified.

Build the package by Maven

kyle-no-MacBook:higeproject kyle$ ls -l
total 8
-rw-r--r--+ 1 kyle  staff  825  2 23 17:27 pom.xml
drwxr-xr-x+ 4 kyle  staff  136  2 23 17:23 src
drwxr-xr-x+ 9 kyle  staff  306  2 23 17:27 target
kyle-no-MacBook:higeproject kyle$ pwd
/Users/kyle/Documents/workspace/higeproject
kyle-no-MacBook:higeproject kyle$ mvn clean package
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building higeproject 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ higeproject ---
[INFO] Deleting /Users/kyle/Documents/workspace/higeproject/target
[INFO] 
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ higeproject ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 0 resource
[INFO] 
[INFO] --- maven-compiler-plugin:2.5.1:compile (default-compile) @ higeproject ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ higeproject ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 0 resource
[INFO] 
[INFO] --- maven-compiler-plugin:2.5.1:testCompile (default-testCompile) @ higeproject ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ higeproject ---
[INFO] 
[INFO] --- maven-war-plugin:2.2:war (default-war) @ higeproject ---
[INFO] Packaging webapp
[INFO] Assembling webapp [higeproject] in [/Users/kyle/Documents/workspace/higeproject/target/higeproject-0.0.1-SNAPSHOT]
[INFO] Processing war project
[INFO] Copying webapp resources [/Users/kyle/Documents/workspace/higeproject/src/main/webapp]
[INFO] Webapp assembled in [23 msecs]
[INFO] Building war: /Users/kyle/Documents/workspace/higeproject/target/higeproject-0.0.1-SNAPSHOT.war
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.106s
[INFO] Finished at: Sun Feb 23 17:31:39 JST 2014
[INFO] Final Memory: 9M/245M
[INFO] ------------------------------------------------------------------------
kyle-no-MacBook:higeproject kyle$ unzip -l target/
classes/                        higeproject-0.0.1-SNAPSHOT/     higeproject-0.0.1-SNAPSHOT.war  maven-archiver/                 test-classes/
kyle-no-MacBook:higeproject kyle$ unzip -l target/higeproject-0.0.1-SNAPSHOT.war 
Archive:  target/higeproject-0.0.1-SNAPSHOT.war
  Length     Date   Time    Name
 --------    ----   ----    ----
        0  02-23-14 17:31   META-INF/
      129  02-23-14 17:31   META-INF/MANIFEST.MF
        0  02-23-14 17:31   WEB-INF/
        0  02-23-14 17:31   WEB-INF/classes/
        0  02-23-14 17:31   WEB-INF/lib/
     1986  02-23-14 17:12   WEB-INF/lib/hogeproject-0.0.1-SNAPSHOT.jar
        0  02-23-14 17:31   META-INF/maven/
        0  02-23-14 17:31   META-INF/maven/org.nailedtothex/
        0  02-23-14 17:31   META-INF/maven/org.nailedtothex/higeproject/
      825  02-23-14 17:27   META-INF/maven/org.nailedtothex/higeproject/pom.xml
      121  02-23-14 17:31   META-INF/maven/org.nailedtothex/higeproject/pom.properties
 --------                   -------
     3061                   11 files
kyle-no-MacBook:higeproject kyle$ 
  • We can see that the WAR contains “hogeproject-0.0.1-SNAPSHOT.jar”.

References

  1. Maven - Running Maven


Mocking a HTTP server with WireMock


Posted on Saturday Feb 22, 2014 at 08:47AM in Technology


Environment

  • WireMock 1.4.3
  • HttpClient 4.2.3
  • Oracle JDK7u51

Resources

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.nailedtothex</groupId>
    <artifactId>wiremock</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
        <dependency>
          <groupId>org.hamcrest</groupId>
          <artifactId>hamcrest-core</artifactId>
          <version>1.3</version>
          <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.github.tomakehurst</groupId>
            <artifactId>wiremock</artifactId>
            <version>1.43</version>
            <classifier>standalone</classifier>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>*</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.3.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>fluent-hc</artifactId>
            <version>4.3.2</version>
        </dependency>
    </dependencies>

</project>

HttpFetcher.java

package org.nailedtothex.wiremock;

import java.io.IOException;

import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.fluent.Request;

public class HttpFetcher {

    public String fetchAsString(String url) throws ClientProtocolException, IOException {
        return Request.Get(url).execute().returnContent().asString();
    }
}

HttpFetcherTest.java

package org.nailedtothex.wiremock;

import static com.github.tomakehurst.wiremock.client.WireMock.*;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;

import org.apache.http.client.HttpResponseException;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;

import com.github.tomakehurst.wiremock.junit.WireMockRule;

public class HttpFetcherTest {

    @Rule
    public WireMockRule wireMockRule = new WireMockRule(18089);

    private HttpFetcher instance;

    @Before
    public void init() {
        instance = new HttpFetcher();
        stubFor(get(urlEqualTo("/hoge.txt")).willReturn(
                aResponse().withStatus(200).withHeader("Content-Type", "text/plain").withBody("hoge")));
        stubFor(get(urlEqualTo("/500.txt")).willReturn(
                aResponse().withStatus(500).withHeader("Content-Type", "text/plain").withBody("hoge")));
        stubFor(get(urlEqualTo("/503.txt")).willReturn(
                aResponse().withStatus(503).withHeader("Content-Type", "text/plain").withBody("hoge")));
    }

    @Test
    public void ok() throws Exception {
        String actual = instance.fetchAsString("http://localhost:18089/hoge.txt");
        String expected = "hoge";
        assertThat(actual, is(expected));
    }

    @Test(expected = HttpResponseException.class)
    public void notFound() throws Exception {
        instance.fetchAsString("http://localhost:18089/NOT_FOUND");
    }

    @Test(expected = HttpResponseException.class)
    public void internalServerError() throws Exception {
        instance.fetchAsString("http://localhost:18089/500.txt");
    }

    @Test(expected = HttpResponseException.class)
    public void serviceUnavailable() throws Exception {
        instance.fetchAsString("http://localhost:18089/503.txt");
    }
}

Remarks

  • To check behavior of the mock with browsers, we can set an breakpoint in the test class to prevent shutdown of the mock HTTP server.
    • I have checked that stub urls are working as I expected with firebug.
  • WireMock dependency brings many its dependencies, but I guess that are not necessary because it is classified as standalone, so I just add exclusions and it is working without any problems anyway.

References

  1. WireMock | WireMock
  2. Apache HttpComponents - Apache HttpComponents


How to make git commit to trigger run a Jenkins job


Posted on Friday Feb 21, 2014 at 06:02PM in Technology


Environment

  • Jenkins 1.551
  • git version 1.8.3.4 (Apple Git-47)
  • OS X 10.9.1

Try using curl

  • In this setup, there is no authentication at Jenkins.
curl -X POST http://localhost:18080/job/BuildAndTestHead/build
  • Let's try with dump-header option.
kyle-no-MacBook:Jenkins kyle$ curl -D - -X POST http://localhost:18080/job/BuildAndTestHead/build
HTTP/1.1 201 Created
Location: http://localhost:18080/queue/item/4/
Content-Length: 0
Server: Jetty(8.y.z-SNAPSHOT)

kyle-no-MacBook:Jenkins kyle$ 

Configure a hook of repository

  • Create a file named “post-commit” in .git/hooks directory.
kyle-no-MacBook:hooks kyle$ pwd
/Users/kyle/gits1/hellojenkins/.git/hooks
kyle-no-MacBook:hooks kyle$ ls -l
total 8
-rwxr-xr-x+ 1 kyle  staff  73  2 23 10:50 post-commit
kyle-no-MacBook:hooks kyle$ cat post-commit 
#!/bin/sh
curl -X POST http://localhost:18080/job/BuildAndTestHead/build
kyle-no-MacBook:hooks kyle$ 
  • Now it runs automatically when we commit using git command from cli.

Remarks

  • According to [3], It doesn't work when we commit with Eclipse.
  • So, we might have to config Jenkins to poll the repository periodically.

References

  1. Remote access API - Jenkins - Jenkins Wiki
  2. gitリポジトリの仕込み方 - はこべブログ ♨
  3. eclipse - EGit and post-commit hook - Stack Overflow


How to install, git clone, build and test


Posted on Thursday Feb 20, 2014 at 06:01PM in Technology


Just try to make Jenkins work, and do some typical works (git clone, build, test) with Git and Maven.

Environment

  • Jenkins 1.551
  • Apache Maven 3.1.1
  • git version 1.8.3.4 (Apple Git-47)
  • Oracle JDK7u51
  • OS X 10.9.1

Download and Install

  • OS X Native package is available at [1].
  • The package is a pkg file.
  • Install is easy. we can just open the package and follow instructions.
  • When installation finishes, Jenkins will run automatically at port 8080 and browser will open and going to show localhost:8080, so we have to stop any application servers ran at port 8080 before we start installation.
    • If you missed that point, Jenkins will run automatically after you have stop the application server.
  • Followed this instruction, Jenkins will be installed as a service of OS X so it will be launched every time at system boot.

Configuration of platform specific matters

Change ports of Jenkins

  • I have been used port 8080 for application server, so I don't want to give it to Jenkins.
  • According to [3], this will make Jenkins to use other ports on OS X.
sudo defaults write /Library/Preferences/org.jenkins-ci httpPort 18080
sudo defaults write /Library/Preferences/org.jenkins-ci ajp13Port 18009

Avoid garbled characters for Multi-byte environment

  • This is for Japanese OS X environment
  • Add this line to “/Library/Application Support/Jenkins/jenkins-runner.sh”
export LANG=ja_JP.UTF-8

Use English as UI Language

  • As default, Jenkins use browser's language for UI.
  • Locale Plugin[7] allows to specify language.
  • I prefer English at Jenkins so I have installed it.
  • After plugin installed, go to Configure System
    • Enter “ENGLISH” to Default Language
    • Check “Ignore browser preference and force this language to all users”
    • Click “Save” in the bottom of the page

Restart Jenkins

  • To affect these changes, we have to restart Jenkins.
sudo launchctl stop org.jenkins-ci
sudo launchctl start org.jenkins-ci
  • Now we got to run Jenkins at 18080 port.

Configuration

Make sure that “git” and “mvn” command are installed

kyle-no-MacBook:~ kyle$ which git
/usr/bin/git
kyle-no-MacBook:~ kyle$ git --version
git version 1.8.3.4 (Apple Git-47)
kyle-no-MacBook:~ kyle$ which mvn
/Users/kyle/apps/apache-maven-3.1.1/bin/mvn
kyle-no-MacBook:~ kyle$ mvn --version
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
Apache Maven 3.1.1 (0728685237757ffbf44136acec0402957f723d9a; 2013-09-18 00:22:22+0900)
Maven home: /Users/kyle/apps/apache-maven-3.1.1
Java version: 1.7.0_51, vendor: Oracle Corporation
Java home: /Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre
Default locale: ja_JP, platform encoding: UTF-8
OS name: "mac os x", version: "10.9.1", arch: "x86_64", family: "mac"
kyle-no-MacBook:~ kyle$ 

Install the Git Plugin of Jenkins

  1. Open the Jenkins page.
  2. Click “Jenkinsの管理” (in Japanese messages)
  3. Click “プラグインの管理”
  4. Click “利用可能”
  5. Enter “git plugin” to filter field.
  6. Check “Git Plugin”
  7. Click “ダウンロードして再起動後にインストール”
  8. Installation progress page will be shown.
    • It seems to a static page at first, but it updates on the progress for dynamically so just wait for a while.
    • It takes several minutes for complete.
  9. Confirm all processes are completed
  10. Restart the Jenkins.

Set JAVA_HOME

  • Output of this command would be help for OS X users.
kyle-no-MacBook:~ kyle$ /usr/libexec/java_home -V
Matching Java Virtual Machines (3):
    1.7.0_51, x86_64:   "Java SE 7" /Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home
    1.6.0_65-b14-462, x86_64:   "Java SE 6" /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
    1.6.0_65-b14-462, i386: "Java SE 6" /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home

/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home
kyle-no-MacBook:~ kyle$
  1. Click “Jenkinsの管理”
  2. Click “システムの設定”
  3. Find JDK section.
  4. Click “JDK追加”
  5. Uncheck “自動インストール”
  6. Enter “名前”
  7. Enter “JAVA_HOME”
  8. Click “保存” at the bottom of the page.

Set Path to Maven executable

  1. Click “Jenkinsの管理”
  2. Click “システムの設定”
  3. Find Maven section.
  4. Click “Maven追加”
  5. Uncheck “自動インストール”
  6. Enter MAVEN_HOME
  7. Click “保存” at the bottom of the page.

Make a job

  • At first, we assume that a example maven project is committed to a local repository. it is better if the project contains some JUnit test classes. I have created a project which contains a servlet, a CDI managed bean and a test class for it.
  • This job will do:
    • Retrieve the source tree of a maven project from the Git repository in local filesystem
    • Build a WAR file
    • Run JUnit test

Procedures:

  1. Click “新規ジョブ作成”
  2. Enter “MyJob001” to “ジョブ名”
  3. Check “Maven2/3プロジェクトのビルド”
  4. Click “OK”
  5. Find “ソースコード管理” section.
  6. Check “Git”
  7. Enter “Repository URL”
  8. Find “ビルド” Section
  9. Enter “ルートPOM'
  10. Enter “ゴールとオプション”
  11. Find “ビルド後の処理” Section
  12. Click “ビルド後の処理の追加”
  13. Click “成果物を保存”
  14. Enter “保存するファイル”
  15. Click “保存”
  16. Now I got a job “MyJob001”

Build

  1. Open the job “MyJob001”
  2. Click “ビルド実行”
  3. Wait for a while.
    • It takes really long time for the first time because there are many new dependencies. maybe we should check the console output of Jenkins.
  4. Some minutes later, we got to see fine mark in the dashboard.
  5. Detail page is interesting, we can see that all tests are passed and deliverables at once.
  6. Check the WAR file which have built by Jenkins.
kyle-no-MacBook:hellojenkins kyle$ unzip -l /Users/Shared/Jenkins/Home/jobs/MyJob001/lastSuccessful/org.nailedtothex\$hellojenkins/archive/org.nailedtothex/hellojenkins/0.0.1-SNAPSHOT/hellojenkins-0.0.1-SNAPSHOT.war 
Archive:  /Users/Shared/Jenkins/Home/jobs/MyJob001/lastSuccessful/org.nailedtothex$hellojenkins/archive/org.nailedtothex/hellojenkins/0.0.1-SNAPSHOT/hellojenkins-0.0.1-SNAPSHOT.war
  Length     Date   Time    Name
 --------    ----   ----    ----
        0  02-21-14 11:24   META-INF/
      132  02-21-14 11:24   META-INF/MANIFEST.MF
        0  02-21-14 11:24   WEB-INF/
        0  02-21-14 11:24   WEB-INF/classes/
        0  02-21-14 11:24   WEB-INF/classes/hellojenkins/
      477  02-21-14 11:24   WEB-INF/classes/hellojenkins/HelloBean.class
     1169  02-21-14 11:24   WEB-INF/classes/hellojenkins/HelloServlet.class
        0  02-21-14 11:24   META-INF/maven/
        0  02-21-14 11:24   META-INF/maven/org.nailedtothex/
        0  02-21-14 11:24   META-INF/maven/org.nailedtothex/hellojenkins/
     1053  02-21-14 11:21   META-INF/maven/org.nailedtothex/hellojenkins/pom.xml
      122  02-21-14 11:24   META-INF/maven/org.nailedtothex/hellojenkins/pom.properties
 --------                   -------
     2953                   12 files
kyle-no-MacBook:hellojenkins kyle$ 

Remarks

  • I would also try that other operations such as automated execution or deploy later.

References

  1. Welcome to Jenkins CI! | Jenkins CI
  2. Jenkins を Mac で使う | Hazi.tech
  3. Jenkins Mac OS X InstallerでJenkinsを入れる - IwazerReport
  4. Jenkins の git plugin と git-client plugin の相性に注意 - diary.sorah
  5. Git Plugin の導入に躓いた - おこらない日記
  6. githubとAndroidとJenkinsの素敵な関係 | GeNERACE labo
  7. Locale Plugin - Jenkins - Jenkins Wiki
  8. The Locale plugin - Howto


Just try to use 2nd level cache with WildFly and Hibernate


Posted on Wednesday Feb 19, 2014 at 05:30PM in Technology


Just playing with 2nd level cache that mentioned at [1]. it is a good tutorial so may we only need to refer [1], and this is my notes and logs only.

Environment

  • WildFly 8.0.0.Final (Hibernate 4.3.1)
  • Maven 3.1.1
  • Oracle JDK7u51
  • OS X 10.9.1

Run Maven to get the sample project

kyle-no-MacBook:l2cache kyle$ mvn archetype:generate \
>     -DarchetypeArtifactId=jboss-javaee6-webapp-archetype \
>     -DarchetypeGroupId=org.jboss.spec.archetypes \
>     -DarchetypeVersion=7.1.2.Final \
>     -DgroupId=de.consol.research \
>     -DartifactId=infinispan-jpa-example \
>     -Dversion=1.0-SNAPSHOT \
>     -Dname="Infinispan JPA Example" \
>     -DarchetypeCatalog=http://search.maven.org/remotecontent?filepath=archetype-catalog.xml \
>     -DinteractiveMode=false
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
[INFO] Scanning for projects...
Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-install-plugin/2.4/maven-install-plugin-2.4.pom
Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-install-plugin/2.4/maven-install-plugin-2.4.pom (7 KB at 5.4 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-deploy-plugin/2.7/maven-deploy-plugin-2.7.pom
Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-deploy-plugin/2.7/maven-deploy-plugin-2.7.pom (6 KB at 20.5 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-site-plugin/3.3/maven-site-plugin-3.3.pom
Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-site-plugin/3.3/maven-site-plugin-3.3.pom (21 KB at 51.1 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-site-plugin/3.3/maven-site-plugin-3.3.jar
Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-site-plugin/3.3/maven-site-plugin-3.3.jar (122 KB at 180.7 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-antrun-plugin/1.3/maven-antrun-plugin-1.3.pom
Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-antrun-plugin/1.3/maven-antrun-plugin-1.3.pom (5 KB at 17.0 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-antrun-plugin/1.3/maven-antrun-plugin-1.3.jar
Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-antrun-plugin/1.3/maven-antrun-plugin-1.3.jar (24 KB at 84.3 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-assembly-plugin/2.2-beta-5/maven-assembly-plugin-2.2-beta-5.pom
Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-assembly-plugin/2.2-beta-5/maven-assembly-plugin-2.2-beta-5.pom (15 KB at 55.4 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-plugins/16/maven-plugins-16.pom
Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-plugins/16/maven-plugins-16.pom (13 KB at 47.0 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-assembly-plugin/2.2-beta-5/maven-assembly-plugin-2.2-beta-5.jar
Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-assembly-plugin/2.2-beta-5/maven-assembly-plugin-2.2-beta-5.jar (204 KB at 357.8 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-dependency-plugin/2.8/maven-dependency-plugin-2.8.pom
Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-dependency-plugin/2.8/maven-dependency-plugin-2.8.pom (12 KB at 41.7 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-dependency-plugin/2.8/maven-dependency-plugin-2.8.jar
Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-dependency-plugin/2.8/maven-dependency-plugin-2.8.jar (150 KB at 274.5 KB/sec)
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] >>> maven-archetype-plugin:2.2:generate (default-cli) @ standalone-pom >>>
[INFO] 
[INFO] <<< maven-archetype-plugin:2.2:generate (default-cli) @ standalone-pom <<<
[INFO] 
[INFO] --- maven-archetype-plugin:2.2:generate (default-cli) @ standalone-pom ---
Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/reporting/maven-reporting-api/2.0.8/maven-reporting-api-2.0.8.jar
Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/doxia/doxia-sink-api/1.0-alpha-9/doxia-sink-api-1.0-alpha-9.jar
Downloading: http://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-interactivity-api/1.0-alpha-5/plexus-interactivity-api-1.0-alpha-5.jar
Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/reporting/maven-reporting-api/2.0.8/maven-reporting-api-2.0.8.jar (10 KB at 28.5 KB/sec)
Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/doxia/doxia-sink-api/1.0-alpha-9/doxia-sink-api-1.0-alpha-9.jar (10 KB at 19.8 KB/sec)
Downloaded: http://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-interactivity-api/1.0-alpha-5/plexus-interactivity-api-1.0-alpha-5.jar (14 KB at 26.0 KB/sec)
[INFO] Generating project in Batch mode
[INFO] Archetype repository missing. Using the one from [org.jboss.spec.archetypes:jboss-javaee6-webapp-archetype:7.1.3.Final] found in catalog http://search.maven.org/remotecontent?filepath=archetype-catalog.xml
Downloading: http://search.maven.org/org/jboss/spec/archetypes/jboss-javaee6-webapp-archetype/7.1.2.Final/jboss-javaee6-webapp-archetype-7.1.2.Final.jar
Downloading: http://repo.maven.apache.org/maven2/org/jboss/spec/archetypes/jboss-javaee6-webapp-archetype/7.1.2.Final/jboss-javaee6-webapp-archetype-7.1.2.Final.jar
Downloaded: http://repo.maven.apache.org/maven2/org/jboss/spec/archetypes/jboss-javaee6-webapp-archetype/7.1.2.Final/jboss-javaee6-webapp-archetype-7.1.2.Final.jar (96 KB at 88.0 KB/sec)
Downloading: http://search.maven.org/org/jboss/spec/archetypes/jboss-javaee6-webapp-archetype/7.1.2.Final/jboss-javaee6-webapp-archetype-7.1.2.Final.pom
Downloading: http://repo.maven.apache.org/maven2/org/jboss/spec/archetypes/jboss-javaee6-webapp-archetype/7.1.2.Final/jboss-javaee6-webapp-archetype-7.1.2.Final.pom
Downloaded: http://repo.maven.apache.org/maven2/org/jboss/spec/archetypes/jboss-javaee6-webapp-archetype/7.1.2.Final/jboss-javaee6-webapp-archetype-7.1.2.Final.pom (3 KB at 5.5 KB/sec)
[INFO] ----------------------------------------------------------------------------
[INFO] Using following parameters for creating project from Archetype: jboss-javaee6-webapp-archetype:7.1.2.Final
[INFO] ----------------------------------------------------------------------------
[INFO] Parameter: groupId, Value: de.consol.research
[INFO] Parameter: artifactId, Value: infinispan-jpa-example
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: package, Value: de.consol.research
[INFO] Parameter: packageInPathFormat, Value: de/consol/research
[INFO] Parameter: package, Value: de.consol.research
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: name, Value: Infinispan JPA Example
[INFO] Parameter: groupId, Value: de.consol.research
[INFO] Parameter: jboss-bom-enterprise-version, Value: 1.0.4.Final-redhat-1
[INFO] Parameter: artifactId, Value: infinispan-jpa-example
[INFO] Parameter: enterprise, Value: false
[INFO] project created from Archetype in dir: /Users/kyle/src/l2cache/infinispan-jpa-example
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 18.514s
[INFO] Finished at: Wed Feb 19 17:26:26 JST 2014
[INFO] Final Memory: 14M/245M
[INFO] ------------------------------------------------------------------------

Import the project to Eclipse

  • File - Import - Existing Maven Projects
  • It comes with no errors.

Make the application to use PostgreSQL

This is not necessary for everyone. It comes with internal H2 datasource definition in the application so we can just skip this work.

Create a database

jbatch=# create database infinispan owner kyle encoding 'UTF8' TEMPLATE template0;
CREATE DATABASE
jbatch=# 

Define a data source

data-source add \
 --name=InfinispanExampleDS \
 --driver-name=postgresql \
 --connection-url=jdbc:postgresql://localhost:5432/infinispan \
 --jndi-name=java:jboss/datasources/infinispan-jpa-exampleDS \
 --user-name=postgres \
 --password=***

Delete datasource definition in WEB-INF

delete Deployed Resources/webapp/WEB-INF/infinispan-jpa-example-ds.xml

Deploy

I did it with Eclipse.

  1. Open Servers Window
  2. Right-click WildFly
  3. Add and remove
  4. Add infinispan-jpa-example
  5. Finish

Browse JSF page

  • Browse here
  • When we reload the page, every time it executes SELECT clause. like this:
17:46:37,631 DEBUG [org.hibernate.SQL] (default task-11) select member0_.id as id1_0_, member0_.email as email2_0_, member0_.name as name3_0_, member0_.phone_number as phone_nu4_0_ from Member member0_ order by member0_.name asc
17:46:39,055 DEBUG [org.hibernate.SQL] (default task-12) select member0_.id as id1_0_, member0_.email as email2_0_, member0_.name as name3_0_, member0_.phone_number as phone_nu4_0_ from Member member0_ order by member0_.name asc
17:49:13,527 DEBUG [org.hibernate.SQL] (default task-10) select member0_.id as id1_0_, member0_.email as email2_0_, member0_.name as name3_0_, member0_.phone_number as phone_nu4_0_ from Member member0_ order by member0_.name asc
  • One test data is already registered when we browse the page.

Send GET request

kyle-no-MacBook:infinispan-jpa-example kyle$ curl http://localhost:8080/infinispan-jpa-example/rest/members/0 
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><member><email>john.smith@mailinator.com</email><id>0</id><name>John Smith</name><phoneNumber>2125551212</phoneNumber></member>kyle-no-MacBook:infinispan-jpa-example kyle$ 

It executes SQL for every request.

17:55:28,664 DEBUG [org.hibernate.SQL] (default task-6) select member0_.id as id1_0_0_, member0_.email as email2_0_0_, member0_.name as name3_0_0_, member0_.phone_number as phone_nu4_0_0_ from Member member0_ where member0_.id=?
17:55:28,665 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-6) binding parameter [1] as [BIGINT] - [0]

Modify persistence.xml to use l2-cache

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
   xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="
        http://java.sun.com/xml/ns/persistence
        http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
   <persistence-unit name="primary">
      <!-- If you are running in a production environment, add a managed 
         data source, the example data source is just for development and testing! -->
      <jta-data-source>java:jboss/datasources/infinispan-jpa-exampleDS</jta-data-source>
      <shared-cache-mode>DISABLE_SELECTIVE</shared-cache-mode>
      <properties>
         <!-- Properties for Hibernate -->
         <property name="hibernate.hbm2ddl.auto" value="create-drop" />
         <property name="hibernate.show_sql" value="false" />
         <property name="hibernate.cache.use_second_level_cache" value="true"/>
      </properties>
   </persistence-unit>
</persistence>

Send GET request again

  • Now SQL is executed only once.

Browse JSF page again

  • It still executes SQL every time I reload. why?

Make the application to allow to use l2-cache for queries

In reference to [2], we still have to modify some codes.

Modify persistence.xml

Add this property:

         <property name="hibernate.cache.use_query_cache" value="true" />

Now it is:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
   xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="
        http://java.sun.com/xml/ns/persistence
        http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
   <persistence-unit name="primary">
      <!-- If you are running in a production environment, add a managed 
         data source, the example data source is just for development and testing! -->
      <jta-data-source>java:jboss/datasources/infinispan-jpa-exampleDS</jta-data-source>
      <shared-cache-mode>DISABLE_SELECTIVE</shared-cache-mode>
      <properties>
         <!-- Properties for Hibernate -->
         <property name="hibernate.hbm2ddl.auto" value="create-drop" />
         <property name="hibernate.show_sql" value="false" />
         <property name="hibernate.cache.use_second_level_cache" value="true"/>
         <property name="hibernate.cache.use_query_cache" value="true" />
      </properties>
   </persistence-unit>
</persistence>

Modify the code of JSF page

The query is executed in MemberListProducer#retrieveAllMembersOrderedByName():

   @PostConstruct
   public void retrieveAllMembersOrderedByName() {
      CriteriaBuilder cb = em.getCriteriaBuilder();
      CriteriaQuery<Member> criteria = cb.createQuery(Member.class);
      Root<Member> member = criteria.from(Member.class);
      // Swap criteria statements if you would like to try out type-safe criteria queries, a new
      // feature in JPA 2.0
      // criteria.select(member).orderBy(cb.asc(member.get(Member_.name)));
      criteria.select(member).orderBy(cb.asc(member.get("name")));
      members = em.createQuery(criteria).getResultList();
   }

Add the code that invokes Query#setHint():

setHint("org.hibernate.cacheable", true)

Now the code is:

   @PostConstruct
   public void retrieveAllMembersOrderedByName() {
       CriteriaBuilder cb = em.getCriteriaBuilder();
       CriteriaQuery<Member> criteria = cb.createQuery(Member.class);
       Root<Member> member = criteria.from(Member.class);
       // Swap criteria statements if you would like to try out type-safe criteria queries, a new
       // feature in JPA 2.0
       // criteria.select(member).orderBy(cb.asc(member.get(Member_.name)));
       criteria.select(member).orderBy(cb.asc(member.get("name")));
       members = em.createQuery(criteria).setHint("org.hibernate.cacheable", true).getResultList();
   }

Browse JSF page once again

  • Now SQL is executed only once even I reloaded many times.

Remarks

  • As default, 2nd level cache is disabled for queries.
    • It seems enabled for operations like EntityManager#find() only.
    • Every time queries need to set hint “org.hibernate.cacheable=true”.
  • According to [3], it seems to there is a way to avoid to invoke annoying setHint() method for every queries.
    • Seems to Query Hints are can define at when we declare Named Query.
    • May I would try it later.

References

  1. Infinispan JPA 2nd Level Caching on JBoss AS 7 – Minimal Working Example – ConSol* Labs
  2. JPAのSecond Level Cacheを試してみる - Starlight
  3. 4.2.3. Query result caching