その手の平は尻もつかめるさ

ギジュツ的な事をメーンで書く予定です

Java でパターンに基いてランダムな文字列を生成できる random-string というのを書いた

Java 版の random-string を書いたので Maven Central にアップしました.


これはパターンに基いたランダムな文字列を生成する君です.
他言語の実装には PerlString::RandomJavaScriptString_random.js などがあります.
この Java 実装は Perl 版の移植になります *1


使い方としては以下のような感じ.

パターンを使う方法
RandomStringGenerator generator = new RandomStringGenerator();
String randomString = generator.generateFromPattern("cCn!.sb"); // (例えば "aB4@X.Ç" が得られる)
正規表現を使う方法
RandomStringGenerator generator = new RandomStringGenerator();
String randomString = generator.generateByRegex("\\w+\\d*\\s[0-9]{0,3}X"); // (例えば "a5B123 18X" が得られる)


詳しい事は javadoc 等を参照して頂ければと思います.
以上です.よろしくお願いします.


[追記]

セキュアな文字列を生成するわけでは無いので,そういう用途の時は SecureRandom をお使い下さい!!!!!

[追記2]

バグフィックスも兼ねて 1.1.0 を出しました.
一番の変更は,RandomStringGenerator のコンストラクタに Random Class のインスタンスを渡せるようにしたことです.マルチスレッドの兼ね合いなんかで ThreadLocalRandom とかを使いたいこともあると思うので……

実用としては,RandomStringGenerator のコンストラクタには任意の Random Class のインスタンスを渡す事をおすすめします.

*1:まだ入れてない機能 (パターンを自分で定義できる機能とか) がいくつかありますが……

git で管理しているリポジトリの各ブランチの中身をそれぞれ個別のディレクトリにエクスポートする

人生にはこういう事が度々あります.深く考えないようにすることにします.


その結果できたのがこれです.

リポジトリのディレクトリ以下でこのコマンドを叩くとイナフという感じです.


Enjoy!!

Servlet コンテナによって HttpServletRequest#getPart(String name) の挙動が違う

Part gotPart = httpServletRequest.getPart("hoge");

みたいなコードがあった時,送られてきた multipart リクエスト (httpServletRequest) に1つも part が含まれていない場合の挙動が Servlet コンテナによって変わってきます.

送るリクエストはこんな感じ.

HttpPost post = new HttpPost("http://localhost:8080/");
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
HttpEntity entity = builder.build(); // part は空のまま instantiate
post.setEntity(entity);
HttpClient client = HttpClientBuilder.create().build();
HttpResponse response = client.execute(post);

この場合に Tomcat 8.0.20 でこのコードを実行すると,gotPart には null が入ってきますが,
Jetty 9.2.9.v20150224 で実行すると,getPart("hoge") の実行によって IOException が上げられます.
Jetty の実装を見るとリクエストに form-data の行が無かった場合に IOException を上げるようになっているようです.
https://github.com/eclipse/jetty.project/blob/a3201a3c810da37ad892e62c1f04600dc889d14a/jetty-util/src/main/java/org/eclipse/jetty/util/MultiPartInputStreamParser.java#L490-L491


Jetty が IOException を上げてくるのが良いかどうかはさておき,ここらへん細かい差異があるので実装にあたって注意が必要ですねという印象です.

textsearch_sennaをキレイにアンインストールする

textsearch_sennaというのがあって,これはsennaを使った全文検索postgresqlに提供するために便利な演算子や関数を提供してくれるやつなんですが,これをアンインストールする必要が出てきた時に「インストール時に追加された関数とか演算子とかビューとか全部調べて手で削除しないとマズいのかーうへー」とか思ってたんですけど,そんなことする必要無かったのでメモ.


結論からいうと,$PG_HOME/share/contrib/uninstall_textsearch_senna.sqlを流し込んでやるとよろしい.このファイルはtextsearch_sennaインストール時に同時に提供されるファイルです.

psql --user=user_name -f $PG_HOME/share/contrib/uninstall_textsearch_senna.sql db_name

これで関連のものがDBから削除されるので,あとはtextsearch_sennaをインストールする時に使ったMakefileを利用して

PATH=$PG_HOME/bin/:$PATH make uninstall

などとしてやると完全にアンインストールされます.ちゃんとアンインストールの為のユーティリティが用意されていた!


ちなみになぜキレイに消し去らなければならないのかというと,pg_updateでpgサーバのバージョンを上げるとなった時に,新しいバージョンではtextsearch_sennaは必要無いのにも関わらず「古いバージョンがtextsearch_senna要求してるけど新しいバージョンにはtextsearch_sennaが入ってないよ〜」とか怒られて死ぬのでそれを回避する為です.
世の中には色々な理由があります.理由があるのです.

Servlet 3.0 から導入された multipart 関連の処理を Tomcat で有効にする術について

servlet 3.0 の multipart 関連処理を有効にする方法 - blog.64p.org
これの関連なんですが.

こういう設定をしておかないと,HttpServletRequest#getPart()HttpServletRequest#getParts() が null を返してきてマジ意味わからん!!!! みたいな感じのキレるが発生いたします.


ところで,Tomcat で multipart 関連の処理を有効にする方法としては

1. web.xml に設定を書く
2. Servlet クラスに対して @MultipartConfig アノテーションで設定する
3. context.xmlTomcat/conf/server.xml に設定を書く

の3つがあるようです.


1の方法は上のtokuhiromさんのエントリにあるように書いてやれば良いです.

<servlet>
    <multipart-config>
        <location>/tmp</location> <!-- ディレクトリパスを指定することも出来る (しなくても良い) -->
        <max-file-size>5242880</max-file-size>
        <max-request-size>27262976</max-request-size>
        <file-size-threshold>32768</file-size-threshold>
    </multipart-config>
</servlet>


2の方法は Servlet クラスに @MultipartConfig アノテーションで設定を書いてやるというものです.

@MultipartConfig(
    location="/tmp", // ディレクトリパスを指定することも出来る (しなくても良い)
    fileSizeThreshold=32768,
    maxFileSize=5242880,
    maxRequestSize=27262976
)

フームという感じです.


3の方法は webapp/META-INF/config.xmlTomcat/conf/server.xml に以下の様な設定を書くという感じのやつです.

<Context
    ...
    allowCasualMultipartParsing="true" />


どれが best-way なのか,という話題ですが,まあアノテーションを使う方法2はちょっと無いですねという感じです.だるいですし,そもそもミドルウェアの関心事がアプリケーションのコードに記述されるというのは厳しい心境になります.

残る方法は1と3ですが,これはまあどちらでも良いのではという感じはあります.
web.xml はアプリケーションの定義を書く xml ですが,まあ multipart の設定を書く程度なら妥当な感じはします (ただ,ディレクトリパスをハードコードで指定したりすると厳しいのではという意識があります).
config.xmlserver.xml に書くのは適切な感じがします.が,web.xml@MultipartConfig アノテーションで出来るような細かな設定が出来ないのでびみょい場合はあると思います.

ここらへんは適宜使い分けていくという感じでしょうか.


参考

GitHub Releases にホストされている成果物の最新の奴を持ってくるワンライナー

GitHub Releases でホストされている任意のリポジトリの成果物の最新のやつを持ってきたくなるという事が人生では常に起こります.そしてそういう時は GitHub API の Releases のやつを使うと良いことがわかっています.

curl https://api.github.com/repos/moznion/java-mysql-diff/releases/latest | jq '.assets[0].browser_download_url' | xargs curl -L -O

簡単ですね! jq 便利!!

:= 演算子をなんと呼ぶのか問題








本当はなんて読むのが正しいんですか.

[追記]