ラベル Java の投稿を表示しています。 すべての投稿を表示
ラベル Java の投稿を表示しています。 すべての投稿を表示

2013年11月8日金曜日

Gradleでfile.encodingをセットする

続けて、超小ネタを投稿。

Gradleでビルドしたjarに日本語クラス名のクラスがある時、そのクラスが見えない現象が発生。結局、jarをビルドした時のfile.encodingがMS932だったのが原因。

解決方法であるこの方法が効かなかったので、別の方法を取ることにした。この解決方法が効かなかったのは、GVMで入れたGradleだからかな?

今回解決したのは、build.gradleに以下を入れる方法。

System.setProperty('file.encoding', 'UTF-8')

Proxy環境でJenkins回すために

久しぶりの投稿。最近は、JavaやらBRMSやらJavaScriptをよくやってます。

今回は、今のプロジェクトで作っているものをJenkinsでビルド→テストしておこうと設定したので小ネタとして投稿。 こういうのは、プロジェクトの初期にやらないと泥沼になると @hideoku に聞いたので、 その教訓を活かしてプロジェクト初期の今のうちに設定。

例によって、Proxy環境に若干苦しめられたけど、なんとか完了。 以下、やったこと。

Jenkinsをyumでインストール

  • /var/lib/jenkinsに入る
  • jenkinsユーザのホームディレクトリもここに
  • GradleプラグインもJenkinsのシステム設定からインストール

Apacheと連携

Jenkinsが標準で使うポートをを他で使ってて、かつURLをhttp://server/jenkinsにしたかったので、/etc/sysconfig/jenkinsを編集

JENKINS_PORT="8084"
JENKINS_AJP_PORT="8010"
JENKINS_ARGS="--prefix=/jenkins"

AntとGradleをインストール

BRMS系のパッケージ作りはAntでのビルド、それを使う周辺はGradleでのビルドなので、両方ともインストール。

Jenkinsのシステム設定を見ると、自動インストールできそうだったけど、JDK以外は自動インストールが上手く行かなかったので、手動でインストールすることに。

と言っても、両方ともバイナリー版をダウンロードして、/usr/localにantとgradleとして置いて、/etc/profileに設定追加しただけ。

  export GRADLE_HOME=/usr/local/gradle
  export ANT_HOME=/usr/local/ant
  export PATH=$PATH:$GRADLE_HOME/bin:$ANT_HOME/bin

GradleのProxy設定

Gradleのビルド途中でdependency解決でインターネットに接続するけどProxy環境なので、/var/lib/jenkins/.gradle/gradle.propertiesを作成。

systemProp.http.proxyHost=proxy.jp
systemProp.http.proxyPort=8080
systemProp.http.proxyUser=hoge
systemProp.http.proxyPassword=hogehoge
systemProp.http.nonProxyHosts=*.hoge.com|localhost
systemProp.https.proxyHost=proxy.jp
systemProp.https.proxyPort=8080
systemProp.https.proxyUser=hoge
systemProp.https.proxyPassword=hogehoge
systemProp.https.nonProxyHosts=*.hoge.com|localhost

と、まぁこんな感じでJenkins環境ができた。来週からジャンジャンJavaとルールとJUnitテスト書かねば。

2010年12月18日土曜日

VDM++とJavaのコンストラクタ

VDM++はオブジェクト指向で、Javaを参考にした面もあって、似ている部分がたくさんある。今回は、VDM++とJavaで色々並べて書いてみようと思う。ちょっと長いです。

デフォルトコンストラクタと引数ありコンストラクタ

VDM++

class Super
  operations
    public Super : () ==> Super
    Super() == def - = new IO().echo("Super class constructor called.¥n") in skip;
end Super

class Child is subclass of Super
  operations
    public Child : () ==> Child
    Child() == def - = new IO().echo("Child class constructor called.¥n") in skip;
    
    public Child : seq of char ==> Child
    Child(s) == def - = new IO().echo(s ^ "¥n") in skip;
end Child

Java

これをJavaで書くとこうなる。VDM++との違いは、記法の違いぐらいしかない。
※ 実行できるように、mainメソッドを追加してます

public class Super {
  public Super() {
    System.out.println("Super class constructor called.");
  }
}

public class Child extends Super {
  public Child() {
    System.out.println("Child class constructor called.");
  }

  public Child(String s) {
    System.out.println(s);
  }
  
  public static void main(String[] args) {
    new Child();
    new Child("aaa");
  }
}

実行してみても、まったく同じ。

VDM++

インタープリタでコマンドを入力
>> init
>> print new Child()

Super class constructor called.
Child class constructor called.

>> print new Child("aaa")

Super class constructor called.
aaa

Java

Super class constructor called.
Child class constructor called.

Super class constructor called.
aaa

デフォルトコンストラクタなしで引数ありコンストラクタあり

違いが出るのは、こんなコードを書いた時。

VDM++

class Super
  operations
    public Super : () ==> Super
    Super() == def - = new IO().echo("Super class constructor called.¥n") in skip;
end Super

class Child is subclass of Super
  operations
    public Child : seq of char ==> Child
    Child(s) == def - = new IO().echo(s ^ "¥n") in skip;
end Child

Java

public class Super {
  public Super() {
    System.out.println("Super class constructor called.");
  }
}

public class Child extends Super {
  public Child(String s) {
    System.out.println(s);
  }
  
  public static void main(String[] args) {
    new Child();
  }
}

VDM++

これをVDM++は実行するとこうなる。

>> init
>> print new Child()

Super class constructor called.

VDM++では、Childクラスにデフォルトコンストラクタがなくても、実行してくれる。Javaだと、Childクラスに引数ありコンストラクタがあるのにデフォルトコンストラクタがないから、コンパイルが通らない。

番外編

ちなみに、VDM++のコンストラクタで気をつけなければならないケースがある。それはこんなケース。

class Super
  operations
    public Super : seq of char ==> Super
    Super(s) == def - = new IO().echo(s ^ "¥n") in skip;
end Super

class Child is subclass of Super
  instance variables
    i : int := 1;

  operations
    public Child : () ==> Child
    Child() == def - = new IO().echo("Child class constructor called.¥n") in skip;
    
    public getI : () ==> int
    getI() == return i;
end Child

これを、こんな実行するとこうなる。

>> init
>> create child := new Child("aaa")
>> print child.getI()

Run-Time Error 73: 識別子が定義されていないか、初期化されていません

インスタンス変数の初期化がされずに、そのままアクセスするとエラーとなるのだ。

これが起こる条件は以下の通り。

  • 親クラスに引数ありのコンストラクタがある
  • 子クラスには、親クラスにある引数ありコンストラクタがない
  • 親クラスにインスタンス変数がある
  • 子クラスのインスタンスを、親クラスにある引数ありコンストラクタで生成する

この問題は、VDM++におけるオブジェクト指向の取り扱い仕様のせい。現在は、こういった問題も含めて、VDMの言語仕様を決めるLanguage Boardがあって、そこで検討しているので、その結果をVDMToolsにもフィードバックしていけるといいね。。

2010年11月11日木曜日

[Java] 配列をディープコピーする

Javaで配列をコピーする時に、ディープコピーが必要なのに、シャローコピーをしていて、複数のオブジェクトが全て同じ参照になってしまい、ハマったのでディープコピーする方法を残しておく。
配列を、以下のように単純に代入するとシャローコピーになり、配列オブジェクトへの参照がコピーされるだけになる。なので、aaa配列の中身を書き換えると、bbb配列の中身も書き換わる。
String[] aaa = {"1", "2", "3", "4"};
String[] bbb = aaa;
 
System.out.println(Arrays.toString(aaa));
System.out.println(Arrays.toString(bbb));
 
aaa[2] = "7";

System.out.println(Arrays.toString(aaa));
System.out.println(Arrays.toString(bbb));
これを、以下のようにArraysクラスのcopyOfメソッドを使うと、ディープコピーとなり、配列の中身をコピーした別のオブジェクトとしてコピーしてくれるなので、aaa配列の中身を書き換えても。bbb配列の中身は書き換わらない。
String[] aaa = {"1", "2", "3", "4"};
String[] bbb = Arrays.copyOf(aaa, aaa.length);

System.out.println(Arrays.toString(aaa));
System.out.println(Arrays.toString(bbb));

aaa[2] = "7";

System.out.println(Arrays.toString(aaa));
System.out.println(Arrays.toString(bbb));

2010年10月12日火曜日

[Java] TreeMapを全データループするのに拡張for文を使う方法

せっかく仕事でJavaを使う機会を得ているので、ブログにもフィードバック。
今回は簡単な所で、TreeMapをJava 1.5から導入された拡張for文でループする方法。割とIteratorを使って解説してるサイトが多いな、と思ったので。
Map<String, Integer> treeMap = new TreeMap<String, Integer>();

treeMap.put("M00000005", 5);
treeMap.put("M00000004", 4);
treeMap.put("M00000007", 7);
treeMap.put("M00000002", 2);
treeMap.put("M00000010", 10);
treeMap.put("M00000006", 6);
treeMap.put("M00000008", 8);
treeMap.put("M00000009", 9);
treeMap.put("M00000003", 3);
treeMap.put("M00000001", 1);

for (String key : treeMap.keySet()) {
  System.out.println("Value -> " + treeMap.get(key));
}
こんな感じ。もし、Mapのキーじゃなくて、Map自体が欲しければ、こんな感じ。
for (Map.Entry<String, Integer> map : treeMap.entrySet()) {
  System.out.println("Value -> " + map.getValue());
}
Collectionsを全部ループするのに、拡張for文はシンプルに書けるので、最近愛用してる。この方法で、他のMapも取れるはず。