Play 2.4.2 (最新バージョン) フレームワーク アプリケーションで ModelMapper 0.7.4 (最新バージョン) を使用しています。Play 2.4 には内部の Google Guice 依存性注入ソリューションが組み込まれており、Play 2.4 を Spring で動作させるために、アプリケーションは Guice から Spring Framework 依存性注入ソリューションに手動でブリッジされています。つまり、通信は Play から Guice、Spring へと流れます。
物事 (Spring による依存性注入) はうまく機能しているように見えますが、テスト開発環境でランダムな Java クラスが変更されると、Play はクラスまたは webapp を自動的にリロードします。このリロードは一般に問題なく動作しますが、この Play セットアップで ModelMapper が Spring Bean として使用されている場合、ModelMapper で問題が発生するようです。(ただし、セットアップ内で手動で Spring コンテナーを作成し、ModelMapper に Spring Bean として接続することによって、Guice-Spring ブリッジをバイパスしたときに問題を再現できませんでした。)
エラーは次のとおりです。
Caused by: org.modelmapper.ConfigurationException: ModelMapper configuration errors:
1) Failed to configure mappings
1 error
at org.modelmapper.internal.Errors.throwConfigurationExceptionIfErrorsExist(Errors.java:241) ~[modelmapper-0.7.4.jar:na]
at org.modelmapper.internal.ExplicitMappingBuilder.build(ExplicitMappingBuilder.java:207) ~[modelmapper-0.7.4.jar:na]
at org.modelmapper.internal.TypeMapImpl.addMappings(TypeMapImpl.java:72) ~[modelmapper-0.7.4.jar:na]
at org.modelmapper.internal.TypeMapStore.getOrCreate(TypeMapStore.java:101) ~[modelmapper-0.7.4.jar:na]
at org.modelmapper.ModelMapper.addMappings(ModelMapper.java:93) ~[modelmapper-0.7.4.jar:na]
at configs.AppConfig.modelMapper(AppConfig.java:109) ~[na:na]
at configs.AppConfig$$EnhancerBySpringCGLIB$$b19a8688.CGLIB$modelMapper$2(<generated>) ~[na:na]
at configs.AppConfig$$EnhancerBySpringCGLIB$$b19a8688$$FastClassBySpringCGLIB$$1f1c1728.invoke(<generated>) ~[na:na]
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228) ~[spring-core-4.2.0.RELEASE.jar:4.2.0.RELEASE]
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:318) ~[spring-context-4.2.0.RELEASE.jar:4.2.0.RELEASE]
at configs.AppConfig$$EnhancerBySpringCGLIB$$b19a8688.modelMapper(<generated>) ~[na:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_45]
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_45]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_45]
at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_45]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162) ~[spring-beans-4.2.0.RELEASE.jar:4.2.0.RELEASE]
... 64 common frames omitted
Caused by: java.lang.ClassCastException: project.entities.User$$EnhancerByModelMapper$$f1b8f0f9 cannot be cast to project.entities.User
at configs.AppConfig$1.configure(AppConfig.java:106) ~[na:na]
at org.modelmapper.PropertyMap.configure(PropertyMap.java:383) ~[modelmapper-0.7.4.jar:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_45]
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_45]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_45]
at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_45]
at org.modelmapper.internal.ExplicitMappingBuilder.build(ExplicitMappingBuilder.java:195) ~[modelmapper-0.7.4.jar:na]
... 78 common frames omitted
これは、クラスのリロード時にのみ発生し、リロードが行われていない場合には発生しません。また、modelMapper.addMappings(aPropertyMap) を使用しない場合も問題は発生しません。Spring AppConfig クラスは次のようになります。
@Configuration
public class AppConfig {
@Bean
public ModelMapper modelMapper() {
ModelMapper modelMapper = new ModelMapper();
// BEGIN: WITHOUT THE FOLLWOING CODE, it works fine
PropertyMap<CreateUserFormDTO, User> userMap = new PropertyMap<CreateUserFormDTO, User>() {
@Override
public void configure() {
map().setPassword(source.getPassword1());
}
};
modelMapper.addMappings(userMap);
// END
return modelMapper;
}
}
ModelMapper には、プレーンな Spring @Autowire インジェクションを使用してアクセスします。User および CreateUserFormDTO クラスは単なる POJO です。
問題は何でしょうか?