Java EE 8がそろそろ固まってきたのでservlet-spec 4.0のJavaDocを日本語に翻訳し始めた(現在半分完了)

タイトルの通りですが、Java EE 8準拠のservlet-spec 4.0のJavaDocを日本語訳に翻訳し始めてみました。
どうにか半分を越したのでとりあえず公開。
ちまちまやって来月中ぐらいには全部翻訳できそうな感じ。

https://megascus.github.io/servlet-spec/docs/apidocs/

感想

割と後悔している。
ものすごく古い仕様で策定されてまったくJavaDocが更新されていないCookieクラスとか、コピペで作成されたものの差分の修正が甘く明らかに間違った文章になっているFilterやそのサブクラスやそもそも英語としておかしい気がするPushBuilderを筆頭にし、JavaDocタグの使い方を知らないのか?と思われるクラスやら、このドキュメントはサーブレットコンテナのユーザーに向けて書いたのかサーブレットコンテナ自体の実装者に向けて書いたのかがごっちゃになってて非常に難解になっているクラスやらが混ざってて本当にこれはspecなのか・・・・・・?という感じ。

一応githubに上がってたservlet-specの4.0をフォークして作業を始めたのですが、間違ってるのか・・・・・・?
https://github.com/javaee/servlet-spec

といいつつ、まあ、半分は終わってしまったのであと半分も頑張りたい。


ちなみに、今は屈指の勉強会ブームで、その場ではいいだろうけど、資料価値としては低いチュートリアルを日本語化しただけのようなパワーポイントの資料が山ほどできていますが、こういった数年は使われるような大本のドキュメント類を翻訳するような作業に興味がある人はいないんでしょうか?
例えば他のJava EEJavaDocも日本語化されるだけでも非常に有用だと思うのですが。

JPAJavaDocとか日本語訳してくれる人いないかなー。
翻訳してくれる人が居るならいくらでも手伝います。

githubで雑にビルド後の成果物を配る

githubではgithub pagesという機能を使ってウェブサイトを公開することができる。
travis-ciというサービスでは無償でビルドを行いgithub pagesにpushをすることができる。

ということで。


github pagesとしての公開の仕方は以下からproject siteを選ぶことで見ることができる。
https://pages.github.com/

travis-ciからgithub pagesにpushするやり方は以下のページ。
https://docs.travis-ci.com/user/deployment/pages/
githubではgh-pagesというブランチを作成することでgithub pagesに公開することができる(設定が必要)
※gh-pagesブランチを作成していない場合、公開対象として表示されないので注意

Oracle JDBC DriverのJava 8対応版が出ました!(Java 7以前のJDBCドライバは配られなくなった模様)

ついに、Oracle Database 12.2.0.1 からjdbcドライバにJava 8対応版が出ました。(今更かよ)
今まではJava 8から増えたjdbcの新しいメソッド類が実装しなくてもよい(実装されない場合、SQLFeatureNotSupportedExceptionが投げられることがドキュメント化されてしまっていた)ため、Java 7のjdbcドライバの使用を強いられていましたが、ついにJava 8から増えたメソッドも使用することができるようになります。

ダウンロードは以下から
http://www.oracle.com/technetwork/database/features/jdbc/jdbc-ucp-122-3110062.html

ちなみに、増えたメソッドには、PreparedStatementで渡すSQLTypeが今まではintだったのをクラスを渡せるようにしたバージョン等があり、型安全なプログラミングがしやすくなっています。
PreparedStatement

なお、地味につらそうなのが、Java 7以前のjdbcドライバが配られなくなったあたり。これは、Java 7以前は全滅なのでは・・・・・

*追記ここから*
とりあえずは過去バージョンのJDBC driverで新しいバージョンのDBに接続できることは保証されるようです。
http://www.oracle.com/technetwork/database/enterprise-edition/jdbc-faq-090281.html#01_02
次のバージョンでJava 8版しかでないのか、それ以前のも一緒に出るのか次第といったところ?


*追記ここまで*
*追記2ここから*
全部詳しく書いてあった!
*追記2ここまで*


という感じで。

Tomcat 8にantからリモートデプロイする

今更antかよ!というつっこみは置いておいて、
Webに残っているドキュメント類がことごとく古くて使用できなかったので更新メモとして。

1. antのフォルダにTomcatから以下のライブラリをコピーする。

  • catalina-ant.jar
  • tomcat-util.jar

2. Tomcatのconf/tomcat-users.xmlに以下の記載を追加(ユーザー名、パスワードは任意)

<user username="tomcat" password="tomcat" roles="manager-script" />

3. build.xmlに以下のtaskdefを追加

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project basedir="." default="build" name="ant_project">
<taskdef name="deploy" classname="org.apache.catalina.ant.DeployTask"/>
・
・
・

4. あとはdeployタスクを実行

<deploy url="http://localhost:8080/manager/text"
        username="tomcat"
        password="tomcat"
        path="/${ant.project.name}"
        update="true"
        war="${basedir}/target/${ant.project.name}.war" />

username/passwordはtomcat-users.xmlで指定したもの。

antタスクの依存ライブラリが増えてた。

という感じで。

2017/06/01追記
最初はlocalWarというのが増えたとか書いてたけど、単純にTomcatのバグを踏んでいただけだった・・・・・・
バージョンによっては上の設定だと動かないのでご注意を。
動かない場合は、以下のパッチで直ってますのでantの依存ライブラリだけ入れ替えてあげればおk。
https://github.com/apache/tomcat/commit/a64839abf2f4eafb48b738794588a4a99ece0320

SpotBugs 3.1.0 RC2を使用してみた。

けっこうはまったのでメモとして。

SpotBugsはfindbugs本体の開発がアレな状態なのでフォークして生まれたツールです。
生まれてまだ日が浅いため、FindBugsとの互換性がけっこう高いです。
なので、FindBugsを使用していた人がSpotBugsに乗り換えられるようにということで、実行までのメモ。

バイナリとしての配布はされていない?ようなので、自前でビルドをする必要があります。
以下のサイトから落としてきてください。
https://github.com/spotbugs/spotbugs

ドキュメントには
gradlew buildを実行すれば普通に出来るよぐらいに書いてありますが、できません。
一部コマンドがgitに依存しているため、gitをインストールしていない場合(Download ZIPでダウンロードしてきた場合)はspotbugs/build.gradleの155行目〜159行目までをコメントアウトしてください。*1

task distSrcZip(type:Exec) {
  commandLine 'git', 'archive', '-o', "${buildDir}/distributions/spotbugs-${project.version}-source.zip",
    '--prefix', "spotbugs-${project.version}/", 'HEAD'
}
tasks['assembleDist'].finalizedBy distSrcZip

//task distSrcZip(type:Exec) {
//  commandLine 'git', 'archive', '-o', "${buildDir}/distributions/spotbugs-${project.version}-source.zip",
//    '--prefix', "spotbugs-${project.version}/", 'HEAD'
//}
//tasks['assembleDist'].finalizedBy distSrcZip

チケット切った。(修正済み)
https://github.com/spotbugs/spotbugs/issues/178

これでビルドが出来るはずです。

ビルド後にdestributionsに入ってるzipを使用するのが正しいです。
間違えてもlibsに入ってるjarを使用してみようとしてはいけない。(間違えた)

mavenの場合

以下のチケットに書いてあるとおり、maven-findbugs-pluginからfindbugsへの依存をSpotBugsに入れ替えてあげればよいらしい。
https://github.com/spotbugs/spotbugs/issues/8

なお、この場合は上記の自前でのコンパイルは不要。
ちゃんと最新版の3.1.0-RC2もmaven centralにリリースされています。


antの場合

antから使用する場合、たぶん、SpotBugsのantプラグインを利用すればいい(はずな)のですが、findbugsからのお試しということで、findbugsのantプラグインを使用できるように以下のように修正します。

  • FINDBUGS_HOMEをspotbugsのフォルダに変更する。
  • lib/spotbugs.jarをlib/findbugs.jarにリネーム

これだけで、SpotBugsが呼び出せるはずです。

使用した感想

判っていたことですが、本家findbugsがパッチを取り込んでくれなくなってしまったため立ち上がったプロジェクトで本家findbugsが正常に稼動しなおしたらこのプロジェクトも終了するって公言されていることもあり、互換性が保たれたままfindbugsのように使用できる、ただしそれを超えたものを期待するものでもないのかなぁという印象です。
環境周りは本家ツールに対してやはりつらい。。。。。。
cccでのセッションでは20%以上の高速化が測られているとのことでしたので、現状としてはそれがどうしても欲しい人向けではないでしょうか。

    • -

2017/05/26 追記

自分の環境(Windows Server 2012 R2 + JDK8u102)ではspotbugsを使用すると逆に20%ほど動作が伸びてしまう結果となりました。
セッション内では高速化が図られているとの話でしたが、環境によるのかもしれません。ご注意ください。

*1:現在はすでに修正されています。

セキュリティさくら分科会(仮称)第二回に参加してきた

なにやってたかの全容は以下の記事を参照。
http://calmery.hatenablog.com/entry/2017/05/14/221218

Docker上でStruts2アプリケーションを動かしたけど、そもそもTomcatってなによ?ってところの説明が抜けていたので、後ろのほうのメンバーは完全に?????という状態になっていた(ので軽く追加説明はした)
せっかくStruts2のサンプルアプリケーションのwarをデプロイしたのにアプリケーションの画面を見ることなく、Tomcatにアクセスだけして終わってたし・・・・・・
ちなみに、dockerのアプリケーションを動かした時点で、以下のURLにアクセスするとデプロイしたStruts2アプリケーションに繋がります。
http://localhost:8080/struts2-rest-showcase

ただ、初回起動時に、勝手にセッションidがURLについてしまってエラーになるので、2回上のURLにアクセスする必要がある模様。*1

なお、この名前はDockerfileで読み込んでるwarファイルの名前と一緒になります。

私は裏側でTomcatの設定ファイルをDockerfileから追加してTomcatの挙動が変わるよたのしー。とかやってたけど、今回の感じだとStruts2のアプリケーションを脆弱性で壊してみてもDockerを起動しなおすと元に戻っちゃうよみたいなところをやったほうが判りやすかったんじゃないだろうか?とは思った。

ただ、Dockerやらないとなぁと思いつつやれてなかったのを一歩踏み出せたというのはありがたい。

*1:これはたぶんサンプルアプリケーションのバグ。直さないけど

Javaの文字列変換にどれくらい時間がかかってるかを測定してみる

前回の記事で、文字として扱わない状態で改行コードで分割することでパラレル実行向けに最適化されたようだと書きましたが、そういえば、Javaのバイトからの文字列への変換にどれくらいコストがかかるのかを調べたことがなかったので、調べました。

なお、環境は前回と同じ。
PCとしては5年ぐらい前のCore i7だけどHDDなWindows 10のものを使用しています。
使用したJavaのバイナリはjdk-9-ea+167_windows-x64_bin.exeです。

ということで、以下の3通りで調べました。


//文字列として扱う
BufferedReader reader = Files.newBufferedReader(Paths.get(fileName));
while (reader.readLine() != null) {
}
//InputStreamで読む
InputStream inputStream = Files.newInputStream(Paths.get(fileName));
byte[] buff = new byte[8192];
while (inputStream.read(buff) == 8192) {
}
//InputStreamで読んだ後に文字列に自前で変換する。(参考用)
InputStream inputStream = Files.newInputStream(Paths.get(fileName));
byte[] buff = new byte[8192];
while (inputStream.read(buff) == 8192) {
    new String(buff);
}

ちなみに、InputStreamで使用されているバッファサイズ(8192)はBufferedReaderを作成する場合にデフォルトで使用されるバッファサイズです。
BufferedReaderとバッファサイズを併せました。
参考用は前回作成したテストデータだとBufferedReaderのほうがループ回数が極端に多くなってしまうため、ループ回数の差がどれくらいの影響を与えてるのかを見るための参考用のデータです。BufferedReaderの中ではバッファの中からさらに1行ごとに文字列を生成されているはず。

結果

  • BufferedReader->7.2秒ぐらい
  • InputStream->0.9秒ぐらい
  • InputStreamで自前で文字列化->5秒ぐらい

やはりそれなりに時間がかかるんだなぁという印象でした。

使ったコードはこちら
https://gist.github.com/megascus/04cab0e0c90d640c2e575e69c77546c4