JenkinsでNoSuchMethodError(Java)
メモ
JenkinsでMavenプロジェクト(JavaのWebアプリ)を自動ビルドさせてできたwarファイルをデプロイするとjava.lang.NoSuchMethodErrorが発生しました。
原因は何かというと、古い状態のままコンパイルされた状態のclassファイルが有効になっていたため。
例えば、
TestA.java
public class TestA { public String test(Integer arg) { return arg.toString(); } }
TestB.java
public class TestB { public void test() { TestA testA = new TestA(); Integer arg = 100; testA.test(arg); } }
ですでにmaven packageされているものがあったとして、TestA.javaを
public String test(Number arg) { return arg.toString(); }
のように仮引数の型をInteger->Numericに書き換えて再度maven packageをしようとすると、TestB.classは再コンパイルされずにTestA#test(Integer arg)を参照に行ってエラーとなっていたものと考えられます。
この対応としてJenkinsのプロジェクト設定から
ビルド>ゴールとオプションの項目を「clean package」として毎回maven cleanさせることで回避できました。
ただし、これだけだとcleanされるのはプロジェクト直下のtargetフォルダ(プロジェクトの設定によっては変わることがあると思います)の中だけ。
今回はさらに、WEB-INF/classesとWEB-INF/libもビルドの度に作り直したほうがよさそうだったのでそれも設定しました。
WEB-INF/libはそのままにしておくと、ライブラリのバージョン指定を変更した場合に複数のバージョンが同時に存在する状態(古いバージョンが残って新しいバージョンが追加される)になるのでクリアは必須と思われます。
pom.xmlのbuild>pluginsに追加
<plugin> <artifactId>maven-clean-plugin</artifactId> <version>2.4.1</version> <configuration> <filesets> <fileset> <directory>src/main/webapp/WEB-INF/classes</directory> </fileset> <fileset> <directory>src/main/webapp/WEB-INF/lib</directory> </fileset> </filesets> </configuration> </plugin>
バージョンは適切なものに置き換えてください。directoryタグの中身もプロジェクトの構成に従って書き換えてください。