SpringでNotWritablePropertyExceptionが出たときの対処

仕事でJava書くの久しぶりすぎてよくわからん…

Spring Framework を利用してWEBアプリケーションのサービス層に Dependency Injection するところで org.springframework.beans.NotWritablePropertyException が出て動作しなくなってしまった。

原因はしょぼミスだったものの、調べてみてようやく仕組みが理解できたのでメモにして残すことにする。

Java側はこんな感じ(ソースコード持ち出せないので、@ITのサンプルで代替…)。

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringTest  {
   public static void main(String args[]){
      // アプリケーションコンテキストの取得
      ApplicationContext contxt =
         new ClassPathXmlApplicationContext("applicationContext.xml");

      // Beanの取得
      Target target = (Target)contxt.getBean("target");

      System.out.println( target.getMessage());
   }
}

applicationContext.xml はこんな感じ(こちらも実際はファイル名違うけど)。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
   <bean id="target" class="Target" >
      <property name="message" >
         <value>Hello World!</value>
      </property>
   </bean>
</beans>

用途こそ違うものの、構造としてはほぼ一緒。実際は、WEBアプリケーションのサービス層(ビジネスロジック層?)にDAOや共通部品を組み込むために使用している。

で、NotWritablePropertyExceptionが出るのは Injection する対象のクラスに setter が存在しない場合。通常はこれが出たら setter が存在することと、 setter の名前が正しいことを確認すればOK。 setter も正しかったら…デプロイする資源間違ってんじゃないの?って話。

ちなみに、今回は単純にデプロイする資源が間違っていて、 setter を追加する前の状態のクラスファイルがアプリケーションサーバに上がっていたことが原因。 Eclipse のプロジェクトの設定が間違っていて、ビルドした資源が /WEB-INF/classes ではなく /bin に出力されるようになっていたことに気づかず、 /WEB-INF/classes にある古い資源を何度もデプロイしていたという。新人かよ。

それにしても、プロジェクトをチェックアウトしたときに設定がおかしくなるのも考え物。プロジェクトの設定ごとバージョン管理に入れておいたらいいのかな。


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>