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

この日記は私的なものであり所属会社の見解とは無関係です。 GitHub: takahashikzn

HikariCP-2.2.5とJavassist-3.19.0の組み合わせでVerifyError、そして初のPR

Maven CentralにJavassist-3.19.0が登録されていたので、早速試してみたところ、この有り様。

Caused by: java.lang.VerifyError: Illegal type at constant pool entry 417 in class com.zaxxer.hikari.proxy.PreparedStatementJavassistProxy
Exception Details:
  Location:
    com/zaxxer/hikari/proxy/PreparedStatementJavassistProxy.setObject(ILjava/lang/Object;Ljava/sql/SQLType;)V @4: invokespecial
  Reason:
    Constant pool index 417 is invalid
  Bytecode:
    0x0000000: 2a1b 2c2d b701 a1a7 000c 3a04 2a19 04b6
    0x0000010: 001b bfb1                              
  Exception Handler Table:
    bci [0, 7] => handler: 10
  Stackmap Table:
    full_frame(@10,{Object[#2],Integer,Object[#285],Object[#412]},{Object[#17]})
    same_frame(@19)

	at com.zaxxer.hikari.proxy.ProxyFactory.getProxyPreparedStatement(ProxyFactory.java) ~[HikariCP-2.2.5.jar:na]
	at com.zaxxer.hikari.proxy.ConnectionProxy.prepareStatement(ConnectionProxy.java:280) ~[HikariCP-2.2.5.jar:na]
	at com.zaxxer.hikari.proxy.ConnectionJavassistProxy.prepareStatement(ConnectionJavassistProxy.java) ~[HikariCP-2.2.5.jar:na]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_25]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_25]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_25]
	at java.lang.reflect.Method.invoke(Method.java:483) ~[na:1.8.0_25]

VerifyErrorなんて、普段は絶対にお目にかからない珍しいエラーです。
バイトコードを意図的に改変しない限り、通常は発生しません。


HikariCPは、ラッパークラスを単純なデリゲート*1ではなく、Javassistを用いた動的クラス生成により実現しています。


理由は「単にメソッド呼び出しをフォワードするだけのアホみたいなソースを書くのが嫌」だからである、とどこかで読んだような気が。
↑ウソでした。すいません。パフォーマンス上の理由のようです。
http://github.com/brettwooldridge/HikariCP/wiki/Down-the-Rabbit-Hole


でもまあ、あまりやり過ぎるとこうなるわけでして、何事もバランスが大事ということかもしれません。

初のPR

何事も経験ということで、上記不具合を修正して初のプルリクエストをやってみました。

http://github.com/brettwooldridge/HikariCP/pull/223

PR1時間後の追記


改めて見なおしてみると、Java7では動かないコードをPRしてしまいました。

一旦PRしてしまうと、コミットを操作する手段は無いだろうと思っていたので、


\(^o^)/オワタァァァ


な気分でしたが、PRの元となったリモートブランチへpushすれば、PRも自動的に追従されました。何と便利な…

2014-01-08追記

若干手直しされたものの、特に問題なくマージしてもらえました。わぁい。
お礼のメッセージも頂きました。ちょっと嬉しいかも...!!

*1: 例えばHttpServletRequestWrapperのようなヤツ