読者です 読者をやめる 読者になる 読者になる

Mavenの各種ディレクトリに対応するプロパティの一覧

はじめに

Mavenで提供されているプロパティの名前を調べ直すことが度々あるので、調べた内容をメモしておく。 「使えるプロパティのリストはこれですよ」ときちんと書いてある公式ドキュメントは、あるような、ないような。。。 まぁ、Mavenがプロパティの塊で、なおかつモジュールも細分化されているから、統合的なドキュメントが書きにくいのは分からなくもない。

ひとまず、よく利用するものだけまとめておく。

各種ディレクトリに対応するプロパティの一覧

プロパティ デフォルト値 対応するpom.xmlの要素の位置(XPath)
project.basedir (プロジェクトのディレクトリへのフルパス) (なし)
project.build.directory ${project.basedir}/target /project/build/directory
project.build.outputDirectory ${project.basedir}/target/classes /project/build/outputDirectory
project.build.testOutputDirectory ${project.basedir}/target/test-classes /project/build/testOutputDirectory
project.build.sourceDirectory ${project.basedir}/src/main/java /project/build/sourceDirectory
project.build.scriptSourceDirectory ${project.basedir}/src/main/scripts /project/build/scriptSourceDirectory
project.build.testSourceDirectory ${project.basedir}/src/test/java /project/build/testSourceDirectory

TODO

ディレクトリ ${project.basedir}/src/main/resources に対応するプロパティの型はStringかFileの配列だったかも。 今後必要ならば、上記の表に型の情報を追加して、プロパティの一覧を増やす。

参考

viでたまに利用するコマンド

たまに必要になって毎回調べ直すので、メモしておく。

行番号の表示

カーソルモードで以下のコマンドを実行。

:set number

実行前の例は以下。

#include <stdio.h>

main( )
{
    printf("hello, world\n");
}

実行後の例は以下。

      1 #include <stdio.h>
      2 
      3 main( )
      4 {
      5     printf("hello, world\n");
      6 }

AspectJを利用したプロジェクトのMavenでのビルドとテスト (Load-Time Weaving)

はじめに

あるOSSの解析のためにAspectJを利用した。 その際にMavenアスペクトのビルドとテストを行ったので、その記録を残しておく。 ここでは、テストメソッドにログ出力を織り込むことにする。

ディレクトリ構成

$ tree
.
|-- pom.xml
`-- src
    |-- main
    |   |-- java
    |   |   `-- redj
    |   |       `-- aspectj
    |   |           `-- LoggingAspect.java
    |   `-- resources
    `-- test
        `-- java
            `-- redj
                `-- aspectj
                    `-- LoggingAspectTest.java

LoggingAspect.java

アスペクトを準備。 パッケージredj.aspectjの任意のクラスにおいて、testをプレフィックスに持つメソッドの実行前にログを出力する。

package redj.aspectj;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class LoggingAspect {

    @Pointcut("execution(* redj.aspectj.*.test*(..))")
    public void atTestMethod() {
    }

    @Before("atTestMethod()")
    public void logBeforeTest() {
        System.out.println("***** begin test");
    }
}

LoggingAspectTest.java

テストクラスを準備。 アスペクトが織り込まれるように、testをプレフィックスに持つメソッドを定義しておく。

package redj.aspectj;

import org.junit.Test;

public class LoggingAspectTest {

    @Test
    public void testFoo() {
        System.out.println("test foo");
    }

    @Test
    public void testBar() {
        System.out.println("test bar");
    }
}

pom.xml

testフェーズでLoad-Time Weavingを利用するようにpom.xmlを構成。 かなり面倒。

maven-dependency-plugin:build-classpathを利用してaspectjweaverのJarファイルのパスを組み立てて、maven-surefire-plugin:testに引き渡しているところがポイント。 maven-surefire-plugin:testでは、プロパテイを遅延評価する必要があるので@{ }を利用している。

aspectj-maven-plugin:compileを利用してaop-ajc.xmlを生成する。 aop-ajc.xmlには、aspectjweaverに認識させるアスペクトの定義情報が書かれている。 ただし、aspectj-maven-pluginのcomplianceLevelのデフォルトは1.4なので、明示的に1.5以上に設定しないと、アノテーションを利用したアスペクトコンパイルでエラーを起こす。 さらに、AspectJのバージョンがずれていると警告が出るので、aspectj-maven-pluginにaspectjtoolsへの依存を明示的に書いて、バージョンを合わせる。

<?xml version="1.0" encoding="UTF-8"?>
<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>redj</groupId>
    <artifactId>aspectj</artifactId>
    <version>0.0.1</version>
    <packaging>jar</packaging>

    <properties>
        <!-- maven-compiler-plugin -->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>

        <!-- versions of plugins -->
        <maven-dependency-plugin.version>3.0.0</maven-dependency-plugin.version>
        <aspectj-maven-plugin.version>1.10</aspectj-maven-plugin.version>
        <maven-surefire-plugin.version>2.20</maven-surefire-plugin.version>

        <!-- versions of dependencies -->
        <aspectj.version>1.8.10</aspectj.version>
        <junit.version>4.12</junit.version>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>${maven-dependency-plugin.version}</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>build-classpath</goal>    <!-- binds by default to generate-sources -->
                        </goals>
                        <configuration>
                            <outputProperty>aspectj-weaver-path</outputProperty>
                            <includeGroupIds>org.aspectj</includeGroupIds>
                            <includeArtifactIds>aspectjweaver</includeArtifactIds>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>
                <version>${aspectj-maven-plugin.version}</version>
                <dependencies>
                    <dependency>    <!-- upgrade AspectJ -->
                        <groupId>org.aspectj</groupId>
                        <artifactId>aspectjtools</artifactId>
                        <version>${aspectj.version}</version>
                    </dependency>
                </dependencies>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>    <!-- binds by default to compile -->
                        </goals>
                        <configuration>
                            <complianceLevel>1.8</complianceLevel>
                            <outxml>true</outxml>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>${maven-surefire-plugin.version}</version>
                <executions>
                    <execution>
                        <id>default-test</id>
                        <goals>
                            <goal>test</goal>   <!-- binds by default to test -->
                        </goals>
                        <configuration>
                            <argLine>-javaagent:@{aspectj-weaver-path}</argLine>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>${aspectj.version}</version>
        </dependency>

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>${aspectj.version}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

ビルド

テストメソッドの実行前にログが出力されていることが確認できる。

$ mvn clean install
(略)
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running redj.aspectj.LoggingAspectTest
***** begin test
test bar
***** begin test
test foo
[INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.153 s - in redj.aspectj.LoggingAspectTest
(略)

参考

Javaのシステムプロパティの一覧表示

過去に何度か同じ使い捨てのコードを書いたので、また必要になった時のために残しておく。

public class Main {

    public static void main(String[] args) {
        System.getProperties()
                .entrySet()
                .stream()
                .sorted((x, y) -> x.getKey().toString().compareTo(y.getKey().toString()))
                .forEach(entry -> System.out.println(entry.getKey() + " = " + entry.getValue()));
    }
}

Windows版のDocker Engineのリスト

Microsoftのドキュメント「Windows Containers on Windows Server」の手順では、OneGetを利用してDocker Engineを取得する。 OneGetを実行すると、Azure StorageからDocker Engineの実行バイナリを取得するようだ。 直接以下のAPIを実行すると、配置されているDocker Engineの一覧を取得することができる。

http://dockermsft.blob.core.windows.net/dockercontainer?resType=container&comp=list

執筆時点でのAPIの実行結果(自分で整形)は以下。 JSON形式では返せない模様。

<?xml version="1.0" encoding="utf-8"?>
<EnumerationResults ContainerName="http://dockermsft.blob.core.windows.net/dockercontainer">
  <Blobs>
    <Blob>
      <Name>DockerMsftIndex.json</Name>
      <Url>http://dockermsft.blob.core.windows.net/dockercontainer/DockerMsftIndex.json</Url>
      <Properties>
        <Last-Modified>Wed, 05 Apr 2017 22:38:24 GMT</Last-Modified>
        <Etag>0x8D47C74784ED01A</Etag>
        <Content-Length>5032</Content-Length>
        <Content-Type>application/octet-stream</Content-Type>
        <Content-Encoding/>
        <Content-Language/>
        <Content-MD5>TAIVvNh/G6LpvBFeeohrWA==</Content-MD5>
        <Cache-Control/>
        <BlobType>BlockBlob</BlobType>
        <LeaseStatus>unlocked</LeaseStatus>
      </Properties>
    </Blob>
    <Blob>
      <Name>docker-1-12-1-cs1.zip</Name>
      <Url>http://dockermsft.blob.core.windows.net/dockercontainer/docker-1-12-1-cs1.zip</Url>
      <Properties>
        <Last-Modified>Thu, 02 Mar 2017 19:33:49 GMT</Last-Modified>
        <Etag>0x8D461A30D591EF4</Etag>
        <Content-Length>13838077</Content-Length>
        <Content-Type>application/octet-stream</Content-Type>
        <Content-Encoding/>
        <Content-Language/>
        <Content-MD5>PzDfmGUp5SqfRVy2/hofog==</Content-MD5>
        <Cache-Control/>
        <BlobType>BlockBlob</BlobType>
        <LeaseStatus>unlocked</LeaseStatus>
      </Properties>
    </Blob>
    <Blob>
      <Name>docker-1-12-2-cs1.zip</Name>
      <Url>http://dockermsft.blob.core.windows.net/dockercontainer/docker-1-12-2-cs1.zip</Url>
      <Properties>
        <Last-Modified>Thu, 02 Mar 2017 19:43:54 GMT</Last-Modified>
        <Etag>0x8D461A475DDC980</Etag>
        <Content-Length>13863262</Content-Length>
        <Content-Type>application/octet-stream</Content-Type>
        <Content-Encoding/>
        <Content-Language/>
        <Content-MD5>p6z/SiiR7R17iABzuNDMxg==</Content-MD5>
        <Cache-Control/>
        <BlobType>BlockBlob</BlobType>
        <LeaseStatus>unlocked</LeaseStatus>
      </Properties>
    </Blob>
    <Blob>
      <Name>docker-1-12-2-cs2-ws-beta.zip</Name>
      <Url>http://dockermsft.blob.core.windows.net/dockercontainer/docker-1-12-2-cs2-ws-beta.zip</Url>
      <Properties>
        <Last-Modified>Wed, 12 Oct 2016 23:48:15 GMT</Last-Modified>
        <Etag>0x8D3F2FA3C4E334E</Etag>
        <Content-Length>14183015</Content-Length>
        <Content-Type>application/octet-stream</Content-Type>
        <Content-Encoding/>
        <Content-Language/>
        <Content-MD5>2b14ZgGoGyBVrtkzwtd34w==</Content-MD5>
        <Cache-Control/>
        <BlobType>BlockBlob</BlobType>
        <LeaseStatus>unlocked</LeaseStatus>
      </Properties>
    </Blob>
    <Blob>
      <Name>docker-1-13-0-rc3.zip</Name>
      <Url>http://dockermsft.blob.core.windows.net/dockercontainer/docker-1-13-0-rc3.zip</Url>
      <Properties>
        <Last-Modified>Thu, 02 Mar 2017 19:47:12 GMT</Last-Modified>
        <Etag>0x8D461A4EBCFFD99</Etag>
        <Content-Length>13911681</Content-Length>
        <Content-Type>application/octet-stream</Content-Type>
        <Content-Encoding/>
        <Content-Language/>
        <Content-MD5>+OR6vKBZbU0aAzjme/hBtw==</Content-MD5>
        <Cache-Control/>
        <BlobType>BlockBlob</BlobType>
        <LeaseStatus>unlocked</LeaseStatus>
      </Properties>
    </Blob>
    <Blob>
      <Name>docker-1-13-0-rc4.zip</Name>
      <Url>http://dockermsft.blob.core.windows.net/dockercontainer/docker-1-13-0-rc4.zip</Url>
      <Properties>
        <Last-Modified>Thu, 02 Mar 2017 19:50:29 GMT</Last-Modified>
        <Etag>0x8D461A56102B607</Etag>
        <Content-Length>13934374</Content-Length>
        <Content-Type>application/octet-stream</Content-Type>
        <Content-Encoding/>
        <Content-Language/>
        <Content-MD5>8iZy1ZG44wwnF11+KOThIA==</Content-MD5>
        <Cache-Control/>
        <BlobType>BlockBlob</BlobType>
        <LeaseStatus>unlocked</LeaseStatus>
      </Properties>
    </Blob>
    <Blob>
      <Name>docker-1-13-1.zip</Name>
      <Url>http://dockermsft.blob.core.windows.net/dockercontainer/docker-1-13-1.zip</Url>
      <Properties>
        <Last-Modified>Fri, 10 Feb 2017 02:51:11 GMT</Last-Modified>
        <Etag>0x8D4515FABC5013F</Etag>
        <Content-Length>14025912</Content-Length>
        <Content-Type>application/octet-stream</Content-Type>
        <Content-Encoding/>
        <Content-Language/>
        <Content-MD5>dkVeRNm5LvDycVg7M2ucWw==</Content-MD5>
        <Cache-Control/>
        <BlobType>BlockBlob</BlobType>
        <LeaseStatus>unlocked</LeaseStatus>
      </Properties>
    </Blob>
    <Blob>
      <Name>docker-17-03-0-ee.zip</Name>
      <Url>http://dockermsft.blob.core.windows.net/dockercontainer/docker-17-03-0-ee.zip</Url>
      <Properties>
        <Last-Modified>Thu, 02 Mar 2017 19:03:54 GMT</Last-Modified>
        <Etag>0x8D4619EDF782BE1</Etag>
        <Content-Length>14027010</Content-Length>
        <Content-Type>application/octet-stream</Content-Type>
        <Content-Encoding/>
        <Content-Language/>
        <Content-MD5>U8846AI0qZef+mg8PbhxhA==</Content-MD5>
        <Cache-Control/>
        <BlobType>BlockBlob</BlobType>
        <LeaseStatus>unlocked</LeaseStatus>
      </Properties>
    </Blob>
    <Blob>
      <Name>docker-17-03-1-ee.zip</Name>
      <Url>http://dockermsft.blob.core.windows.net/dockercontainer/docker-17-03-1-ee.zip</Url>
      <Properties>
        <Last-Modified>Wed, 05 Apr 2017 22:34:08 GMT</Last-Modified>
        <Etag>0x8D47C73DFDE700A</Etag>
        <Content-Length>14029894</Content-Length>
        <Content-Type>application/octet-stream</Content-Type>
        <Content-Encoding/>
        <Content-Language/>
        <Content-MD5>OJHI8eUJ9OR0oxEktszJJQ==</Content-MD5>
        <Cache-Control/>
        <BlobType>BlockBlob</BlobType>
        <LeaseStatus>unlocked</LeaseStatus>
      </Properties>
    </Blob>
  </Blobs>
  <NextMarker/>
</EnumerationResults>

参考

Blob Service REST API - List Containers

JSONの整形

はじめに

LinuxでのJSONの整形方法をメモ。

コマンドjqを利用

$ cat in.json | jq

Ubuntuでjqをインストールする場合は以下。

$ sudo apt-get install jq

CentOSでjqをインストールする場合は以下。

$ sudo yum install jq

Pythonのモジュールを利用

$ cat in.json | python -m json.tool

etcdでよく利用するAPI

はじめに

自分がよく利用するetcdのAPIをメモしておく。

キーの値を取得

キーがfoo/barの場合。

curl http://localhost:2379/v2/keys/foo/bar

キーの値を再帰的に取得

キーがfoo/barの場合。

curl http://localhost:2379/v2/keys/foo/bar/?recursive=true