しおしお

IntelliJ IDEAのことなんかを書いてます

JSLintをantから使ってみる

JSLint(jslint4java)をantから使用する方法

jslint4javaがantのカスタムタスクを持っているので、それを使うだけでいけます。

※JSLintで出来る検査は、こちらを見てね。JSLintについて調べてみた - しおしおの雑記帳

antのビルドスクリプト

<target name="jslint">
  <!-- jslintのタスクを定義 -->
  <taskdef name="jslint" classname="com.googlecode.jslint4java.ant.JSLintTask"
      classpathref="jslint.path" />

  <!-- レポートの出力先の初期化 -->
  <delete dir="report/jslint" />
  <mkdir dir="report/jslint" />

  <!--
  jslintタスクを使用してjsファイルの静的検査
  options属性にjslintに指定するオプションを設定する。
  -->
  <jslint options="indent=2,plusplus,maxlen=120" haltonfailure="false">
    <!--
    結果の出力形式
    開発環境で見やすいplain形式と、CI(Jenkins)を意識したxml形式の2種類を出力
    -->
    <formatter type="plain" destfile="report/jslint/jslint.txt" />
    <formatter type="xml" destfile="report/jslint/jslint.xml" />
    <!-- 検査対象のファイルを指定 -->
    <fileset dir="main/web/js" includes="**/*.js" excludes="**/*jquery*.js,**/*require*.js" />
  </jslint>
</target>

上記のスクリプトは、jslint4java ant taskを元に作っています。

おわり。

JSLintについて調べてみた

JavaScriptの静的検査をやってねってタスクがふってきたので、JSLint(http://www.jslint.com/)でどんな検査ができるか調べてみました。

CIで実行できることが前提なのでjslint4java(http://code.google.com/p/jslint4java/)ってライブラリを使用するので、jslint4javaで使えるオプションのみ調べています。(一部よくわからないのが残っていますが)

ちなみに検査の根拠などは、以下の本に一部書かれています。

JavaScript: The Good Parts ―「良いパーツ」によるベストプラクティス

JavaScript: The Good Parts ―「良いパーツ」によるベストプラクティス

Tolerate bitwise operators

ビット演算子の使用をチェックします。
ビット演算子を許容する場合には、オプション「bitwise」を指定します。

悪い例と検査結果

検査対象コード
function hoge() {
  "use strict";
  var num = 0;

  num &= 0;
  num ^= 0;
  num <<= 2;
}
検査結果
jslint:test.js:5:7:Unexpected '&='.
jslint:test.js:6:7:Unexpected '^='.
jslint:test.js:7:7:Unexpected '<<='.

Assume a browser

一般的なブラウザのグローバル変数の使用をチェックします。
宣言済みとみなす場合には、オプション「browser」を指定します。

悪い例と検査結果

検査対象コード
function hoge() {
  "use strict";
  var XMLHttpRequest2 = new XMLHttpRequest();
  clearInterval(0);
}
検査結果
jslint:test.js:3:29:'XMLHttpRequest' was used before it was defined.
jslint:test.js:4:3:'clearInterval' was used before it was defined.

Tolerate HTML case

htmlタグが全て小文字であることをチェックします。
大文字を許容する場合は、オプション「cap」を指定します。

悪い例と検査結果

検査対象コード
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<Head>
    <Title></title>
</head>
<body>
</body>
</html>
検査結果

1つでもエラーがあったら検査終わり?

jslint:test.html:3:2:Expected 'html' and instead saw 'HTML'.
jslint:test.html:3:2:Stopping.  (33% scanned).

Tolerate continue

continue文の使用をチェックします。
continue文を許容する場合には、オプション「continue」を指定します。

悪い例と検査結果

検査対象コード
function hoge() {
  "use strict";
  var n = 0;
  while (n < 100) {
    if (n % 2 === 0) {
      continue;
    }
  }
}
検査結果
jslint:test.js:6:7:Unexpected 'continue'.

Tolerate CSS workarounds

CSSの先頭行に「@charset」があるかをチェックします。
チェックを行わない場合には、オプション「css」を指定します。

悪い例と検査結果

検査対象コード
body {
    background-color: #f0ffff;
}
検査結果

メッセージから原因を特定するのは難しい気が・・・

jslint:test.css:1:1:'body' was used before it was defined.
jslint:test.css:1:6:Expected an operator and instead saw '{'.
jslint:test.css:1:6:Stopping.  (33% scanned).

Tolerate debugger statements

debugger文の使用をチェックします。
debugger文の使用を許容する場合には、オプション「debug」を指定します。

悪い例と検査結果

検査対象コード
function hoge() {
  "use strict";
  debugger;
}
検査結果
jslint:test.js:3:3:Unexpected 'debugger'.

Assume console, alert, ...

consoleやalertの使用をチェックします。
これらの機能の使用を許容する場合には、オプション「devel」を指定します。

悪い例と検査結果

検査対象コード
function hoge() {
  "use strict";
  console.log('log');
  alert('huga');
}
検査結果
jslint:test.js:3:3:'console' was used before it was defined.
jslint:test.js:4:3:'alert' was used before it was defined.

Tolerate == and !=

「==」や「!=」演算子の使用をチェックします。
「==」や「!=」を許容する場合には、オプション「eqeq」を指定します。

悪い例と検査結果

検査対象コード
var str = '';
if (str == '') {    // 許可されない「==」で比較している。
  str = 'hoge';
}
検査結果
jslint:test.js:2:9:Expected '===' and instead saw '=='.

Tolerate eval

eval関数の呼出をチェックします。
eval関数の呼出を許容する場合には、オプション「evil」を指定します。

eval関数の他にも、Function関数やsetTimeout等の呼出も制限できます。

悪い例と検査結果

検査対象コード
function hoge() {
  "use strict";
  var str = '',
    f;
  eval(str);
  f = new Function(0, 0, 0);
}
検査結果
jslint:test.js:6:3:eval is evil.
jslint:test.js:7:19:The Function constructor is eval.

Tolerate unfiltered for in

for-inループ内でオブジェクトのプロパティを参照する際には、自身のプロパティかのフィルタがかけられているかチェックします。
許容する場合には、オプション「forin」を指定します。

悪い例と検査結果

検査対象コード
function hoge() {
  "use strict";
  var obj = new Array(10),
    key,
    arr = new Array(0);

  for (key in obj) {
    arr.push(obj[key]);     // hasOwnPropertyで自身のプロパティかのチェックをおこなっていない
  }
}
検査結果
jslint:test.js:7:3:The body of a for in should be wrapped in an if statement to filter unwanted properties from the prototype.

Strict white space indentation

インデントのチェック。
デフォルトのチェックは「4」なので、変更する場合には「indent」オプションで指定する。

悪い例と検査結果

indentオプションに「2」を指定した場合(インデントは、2スペースが私の好み)

検査対象コード
function hoge() {
 "use strict";      // 1スペースしかない
  var fuga,
     i;             // 折り返し後が3スペースになっている
}
検査結果
jslint:test.js:2:2:Expected 'use strict' at column 3, not column 2.
jslint:test.js:4:6:Expected 'i' at column 5, not column 6.

Maximum number of errors

エラーとしてレポートする最大数を指定します。
デフォルトは「50」なので、変更する場合は「maxerr」オプションで指定してます。

指定数を超えると、以下の様なメッセージが出力されます。

jslint:test.js:2:2:Too many errors. (40% scanned).

Maximum line length

1行の共用する長さを指定します。デフォルトは無制限(何文字でもOK)?
値の指定は「maxlen」オプションに指定してます。

例えば、120文字を指定した場合で、120文字を超える行があった場合には、以下の様なメッセージが出力されます。

jslint:test.js:3:135:Line too long.

Tolerate uncapitalized constructors

String等のコンストラクタ呼出や、小文字から始まるコンストラクタをチェックします。(多分)
動作確認できず。

検査結果
jslint:test.js:8:15:A constructor name 'fuga' should start with an uppercase letter.
jslint:test.js:9:15:Do not use String as a constructor.

Tolerate dangling _ in identifiers

アンダースコア(_)から開始される変数名や関数名をチェックします。
これらの名前を許容する場合には、オプション「nomen」を指定します。

悪い例と検査結果

検査対象コード
function _hoge() {
  "use strict";
  var _num = 0;
  _num += 1;
}
検査結果
jslint:test.js:1:10:Unexpected dangling '_' in '_hoge'.
jslint:test.js:3:7:Unexpected dangling '_' in '_num'.
jslint:test.js:4:3:Unexpected dangling '_' in '_num'.

Tolerate HTML event handlers

HTML上でのイベントハンドラをチェックします。
許容する場合は、オプション「on」を指定します。

悪い例と検査結果

検査対象コード
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <title></title>
</head>
<body>
<div onclick=""></div>
</body>
</html>
検査結果
jslint:test.html:8:13:Avoid HTML event handlers.

Stop on first error

最初のエラーでチェックを止める場合に、オプション「passfail」を指定します。

このオプションを指定した場合、最初のエラー時に以下のようなメッセージが出力されます。

jslint:test.js:4:7:Combine this with the previous 'var' statement.
jslint:test.js:4:7:Stopping.  (30% scanned).

Tolerate ++ and --

インクリメント、デクリメント演算子の使用をチェックします。
許容する場合には、オプション「plusplus」を指定します。

悪い例と検査結果

検査対象コード
function hoge() {
  "use strict";
  var num = 0;

  num++;
  ++num;
  num--;
  --num;
}
検査結果
jslint:test.js:5:6:Unexpected '++'.
jslint:test.js:6:3:Unexpected '++'.
jslint:test.js:7:6:Unexpected '--'.
jslint:test.js:8:3:Unexpected '--'.

Predefined ( , separated)

宣言されていないグローバル変数の使用をチェックします。
これらを許容する場合には、オプション「predef」に宣言済み変数名をカンマ区切りで指定します。
例えば、$とjQueryを宣言済みとする場合は、「$,jQuery」と指定します。

悪い例と検査結果

検査対象コード
function hoge() {
  "use strict";

  n = n + 1;
}
検査結果
jslint:test.js:6:3:'n' was used before it was defined.

Tolerate . and [^...]. in /RegExp/

正規表現(//)ないでの[^...]の使用をチェックします。
[^...]を許容する場合は、オプション「regexp」を指定します。

悪い例と検査結果

検査対象コード
function hoge(p) {
  "use strict";
  var a;
  a.match(/[^0-9]+/);
}
検査結果
jslint:test.js:4:13:Insecure '^'.

Tolerate missing 'use strict' pragma

use strictの使用漏れをチェックします。
use strictを使用しない場合は、オプション「sloppy」を指定します。

悪い例と検査結果

検査対象コード
function hoge(p) {
  var a;
}
検査結果
jslint:test.js:2:3:Missing 'use strict' statement.

Tolerate inefficient subscripting

プロパティのアクセス時にドッドではなく、を使用しているものをチェックします。
でのアクセスを許容する場合は、オプション「sub」を指定します。

悪い例と検査結果

検査対象コード
function hoge() {
  "use strict";
  var obj,
    a;
  obj.prop = function () {
    return 'fuga';
  };

  a = obj['prop'];  // NG
  a = obj.prop;     // OK
}
検査結果
jslint:test.js:9:11:['prop'] is better written in dot notation.

Tolerate misordered definitions

定義されていないグローバル変数の使用?動作確認できず・・・

Tolerate unused parameters

未使用パラメータのチェック?動作確認できず・・・

Tolerate many var statements per function

変数宣言が関数の先頭で纏めて(単一のvarステートメントで)行われているかをチェックします。
変数宣言を任意の箇所で行うことを許容する場合には、オプション「vars」を指定します。

悪い例と検査結果

検査対象コード
function hoge() {
  "use strict";
  var i;
  var arr = [1, 2, 3];
  for (i = 0; i < arr.length; i += 1) {
    var fuga;
  }
}
検査結果
jslint:test.js:4:7:Combine this with the previous 'var' statement.
jslint:test.js:6:9:Combine this with the previous 'var' statement.

Tolerate messy white space

スペースのチェック・・・
例えば

  • 関数名と開始括弧の間にはスペースは不要
  • 二項演算子の前後にはスペースが必要

などなどをチェックする。かなり厳密にチェックされる?

チェックをやめたい場合には、オプション「white」を指定します。

悪い例と検査結果

検査対象コード
function hoge (){
  "use strict";
  var num=0;
  num+=1;
}
検査結果
jslint:test.js:1:15:Unexpected space between 'hoge' and '('.
jslint:test.js:1:17:Expected exactly one space between ')' and '{'.
jslint:test.js:1:17:Missing space between ')' and '{'.
jslint:test.js:3:10:Missing space between 'num' and '='.
jslint:test.js:3:11:Missing space between '=' and '(number)'.
jslint:test.js:4:6:Missing space between 'num' and '+='.
jslint:test.js:4:8:Missing space between '+=' and '1'.

Assume Windows

Windows関連のライブラリ?の使用をチェック。
許容する場合は、オプション「windows」を指定してあげます。

悪い例と検査結果

検査対象コード
function hoge() {
  "use strict";
  Debug.clear();
  CScript.create();
}
検査結果
jslint:test.js:3:3:'Debug' was used before it was defined.
jslint:test.js:4:3:'CScript' was used before it was defined.

OracleSMIMEとJavaMailで電子署名つきメールの送信

Oracleセキュリティ開発ツールなるものの存在を知ったので、OracleSIME機能を使って電子署名付きメールを送信ししてみました。

このセキュリティ開発ツールは、Oracleデータベースにも同梱されてるんですけど、ライセンスってどうなってるんでしょうかね?
ドキュメントも、Googleさんで検索すると出てくるんですけど、OTNのドキュメントからいこうとすると見つけられないんですよね。

OracleSIMEの詳細は、下のリンク先ページに書かれています。
Oracle S/MIME

環境構築

基本的にクラスパスを設定するだけです。

Oracleセキュリティ開発ツールのjar(下の4ファイル)は、「ORACLE_HOME/jlib」ディレクトリの中にあります。

  • osdt_core.jar
  • osdt_cert.jar
  • osdt_cms.jar
  • osdt_smime.jar

サンプルコード

説明は、コメントで記載しています。(あんまり書いてないですが)

なお、鍵や証明書を読み込む時のパスワードやメールアドレスは、置き換えて考えてください。

結構簡単に署名付きのメールを送信できます。
これをJavaMailのみでやろうとすると、おそらくかなり大変なことになるでしょう。
JavaMailでも、これぐらい簡単に署名付きのメール送信出来るといいんだけどな。

IntelliJでsvn:リポジトリからプロジェクトの作成

IntelliJsvnプラグインの使い方など。

svnからチェックアウトしてプロジェクトの作成

Check out from Version ControlからSubversionを選択します。
下の画像は、プロジェクトを開いてない状態のトップ画面となっていますが、プロジェクトを開いてる場合は、メニューの「VCS->Check out from Version Control」から行えます。
f:id:sioiri:20120728122559p:plain

リポジトリを選択してチェックアウト

基本的に、チェックアウトするのは「trunk」で良いと思います。ブランチやタグは必要となった時に参照できればいいので。
f:id:sioiri:20120728123215p:plain

チェックアウトディレクトリの選択

チェックアウトディレクトリを選択します。trunkディレクトリを作る必要はないので、プロジェクト名を現すディレクトリにチェックアウトしてあげます。

リビジョンを指定してチェックアウトしたい場合は、Specifiedにリビジョン番号をいれてあげます。右側のボタンをクリックするとログからリビジョン番号を選択できます。
f:id:sioiri:20120728123649p:plain

OKを押すと、作業コピーのsvnフォーマットを決めてと言われるので、好きなのを選びましょう。1.7にすると.svnがルートにしかできなくなりますが、作業コピーのバイナリが壊れると、毎回ルートからチェックアウトしないといけなくなります。

チェックアウトしたファイルを元にプロジェクト作成

チェックアウトしたファイルを元にプロジェクト作りますか?と聞かれるので「Yes」を選択してあげましょう。

リポジトリ上のファイルにはソースコードが含まれているので、「Create project from existing sources」にチェックをいれてあげます。
f:id:sioiri:20120728124356p:plain

必要に応じて変更して次へ進みましょう。基本的に変更する必要はないと思いますが。。。
f:id:sioiri:20120728124550p:plain

ソースコードディレクトリを選択してあげます。IntelliJは賢いので、ファイルをスキャンしてソースコードディレクトリを列挙してくれます。不要なディレクトリがある場合はチェック外したりしてあげましょう。
f:id:sioiri:20120728124753p:plain

次はライブラリの選択です。これもIntelliJが良い感じに列挙してくれます。必要が有る場合は、マージしたり除外したりしましょう。
f:id:sioiri:20120728125022p:plain

次はモジュールの作成です。これもいい感じに列挙してくれますが、ProductionとTestが別モジュールになっています・・・。これは、嫌なのでひとつのモジュールにしてあげます。
f:id:sioiri:20120728125250p:plain

モジュールをマージするには、マージしたいモジュール(この場合、MainとTest)を選択して、マージボタンをクリックします。
f:id:sioiri:20120728125452p:plain

新しいモジュールの名前を入れてあげます。
f:id:sioiri:20120728125623p:plain

まーじされて1つのプロジェクトになりましたね。
f:id:sioiri:20120728125716p:plain

完了してプロジェクトの作成は終わりです。
f:id:sioiri:20120728125806p:plain

おわり。

JPOUG>SET EVENTS 20120721に行ってきた!

JPOUG>SET EVENTS 20120721(JPOUG> SET EVENTS 20120721 on Zusaar)に参加してきました。

別にDBエンジニアでもないんだけど、どんなシステムやってもDBはついて回る(最近特にOracleが多い)ので、少しでも勉強になればと思い行ってきました。

セッションは同時並行的に開催される感じだったので、

  • 大人の事情縛りでSQLチューニング
  • Oracle負荷テストツールのまとめ
  • MySql気軽に試す各種機能

を選択して聞いて来ました。

簡単ですが、それぞれのセッションのまとめをしていきます。

大人の事情縛りでSQLチューニング

@さんが説明してくださいました。内容的には、以下ブログの続編のようです。
Mac De Oracle: いん!、イン!、Index どっぷり Inde Only Access生活w - Oracle OpenWorld Unconference presented by JPOUG

大人の事情ってのは、性能出ないんだけど何とかならない?でもSQLいじるとか方式かえるのはダメだよって言われちゃったケースを想定していました。
そんなケースをカバーリングインデックスで乗り切ろうって内容でした。

ぐるぐる系処理

ぐるぐる系処理の場合、ループ1回ごとにDBへの問い合わせが行われます。なので、単発で見た場合問題のないSQLであっても発行回数が多くなり物理I/Oが増大し性能に影響与えちゃいますよと。
これを解決するために、カバーリングインデックスをはって、物理I/Oを極限まで減らしましょうって内容でした。

ただ、バッチ処理をターゲットにした内容でしたが、バッチ処理のぐるぐる系はこんな単純なはなしじゃないかなと。たぶん、カバーリングインデックスをいちいち張っていたら、更新系が持たなくなる気が・・・

スカラー副問い合わせ

スカラー副問い合わせは使ったことないから何が問題かよくわかってなかったけど、絞りこまれたレコード数分実行されちゃうってこと。ようは、単一のSQL文の中にぐるぐる系が潜んでいるので、性能問題が発生しやすいと。これも、スカラー副問い合わせをインデックスアクセスのみで完結するようにカバーリングインデックスをはってあげると物理I/Oを最小限に減らせる。

ただ、大人の事情がなかったらスカラー副問い合わせをやめる選択肢を模索するかな。

仮想列

これは、本来NULLであるべきところにデフォルト値をいれていたので、カーディナリティがおかしくなって性能問題が発生したよって例を元に説明してくれました。これを仮想列を使って、デフォルト値の部分をNULLにしてあげて仮想列をつかって結合とかしましょうとの内容でした。
仮想列は、11gR1からの新機能らしいです。ちょっと勉強しないといけないな。

Oracle負荷テストツールのまとめ

@さんが説明してくださいました。
主に、sh2chさん作のJdbcRunnerの説明でした。(他の製品の簡単な説明もあったけど割愛)
JdbcRunnerの詳細は、JdbcRunner - 汎用データベース負荷テストツール — JdbcRunner v1.2 documentationを参照してください。

このツールは、Javaで作られているので(要JDK6以上)、JDBCドライバさえあればどんなデータベースに対するテストもできること。(公式でテストしているのは、OracleMySqlPostgreSQLらしいです)
今までは、いくつか素晴らしい負荷テストツールがあったけど、やはりデータベース依存であり使いたくても使えないって問題があったので、それを解決するためにつくちゃったみたいです。(すごすぎです!)
また、Javaで作っているので、JITコンパイラの影響で計測が正しく行えないって問題が出たりもするので、ウォームアップ時間を設けて一定時間は性能計測から除外したりとかなり細かい部分まできにして作られているなと思いました。

これは、データベースへたいする負荷テストツールなんでアプリしかやってきてない人なんで、あまりぴんとこなかったりしました。アプリだと、アプリケーション側から負荷かけることしかしないので・・・。
ただ、負荷テストツールを使ってパラメータいじると性能どう変わるか学ぶできるよって話もあったので、まずは勉強のために使ってみようかなと思ってます。
個人的には、このツールのコードのほうが気になるので、コードも読んで勉強したいんですね。

MySql気軽に試す各種機能

主に、MySql Sandboxの説明をしてくださいました。
これは、MySqlを複数バージョンインストールするときに、簡単にバージョンごとに環境つくれたり、レプリ環境を簡単に構築できる優れもの!のようです。

あと、公式からのお願いとしてバイナリリリースを使ってね。(自分でビルドとかあんまりしないでね)とのお話もありました。

MySqlは実務で使ったことないので、ちゃんと勉強しないとなと思ってどれぐらい立つのだろうあか・・・

あんあまりメモ取れなかったので内容薄くなってしまいました・・・。

お礼

最後にスピーカー及びスタッフの皆様、このような機会を提供いただきありがとうございました。

Gradleトーキョーにいってきた!

Gradleトーキョー : ATNDに参加してきたので、簡単に勉強会の内容を纏めてみます。

勉強会の内容

会場につくまで、どんな感じの勉強会になるのかわかりませんでしたが、ハンズオン形式で進んで行きました。(PC持って来といてほんとよかった。)

Gradle入門

講師の@さんのスライド(下のやつ)を元に進んで行きました。
主に以下のことやりましたが、決められた時間の中での作業だったのでかなり必死でした。

  • buildファイルからIDEのプロジェクト作成(私は、IntelliJを使いました。)
  • プロジェクトの属性を参照してみる
  • タスクの作成(依存関係の設定)

プラグインを作ってみよう

Gradleのカスタムプラグインを作ってみような内容でした。
ここもハンズオン形式でしたが、かなりいっぱいいっぱいだったのであまり覚えてない・・・

勉強会とは全く関係ないですが、Sphinxドキュメントをビルドするためのプラグインを作ったことがありますが、かなり無知な状態で作ったので、これを機に勉強しなおしてみようかと思います。
GradleでSphinxをビルドしてみた。 - しおしおの雑記帳

GradleWrapperについて

Gradleの環境構築を行わなくてもGradleを使えるようにする機能。例えば、PJに参画している人全員がGradleの環境構築をしなくてもGradleのビルド実行ができるようになるので、Excel方眼紙の手順書を減らす事ができるようになる。
ただし、インターネットアクセスできないといけないので閉鎖環境では残念ながら使えない・・・。私の職場では、CIサーバから外部にアクセス出来なかったので、Gradle Wrapperを早々に諦めた経験があります。この時は、Gradle Wrapperが何者かを全くわかっていませんでしたが・・・

お礼

主催者の@さん、gradle wrapperの解説をしてくださった@さん、会場を提供してくださったNTTソフトウェア様ありがとうございました。