5

我在使用 Spring Batch 2.1.9 时遇到问题:当我使用jobExplorer.getJobExecution(jobExecutionId)时,当 DAO 必须反序列化如下字符串时,我发现了一个问题:

{"map":[{"entry":{"string":"parsedComparingDate","date":"2014-03-08 23:00:00.0 UTC"}}]}

BATCH_JOB_EXECUTION_CONTEXT表中,使用方法JdbcJobExecutionDao.getJobExecution()

我知道春季批处理使用 xstream 1.3,但在我的 Pom 中,我有:

  • 弹簧批次 2.1.9
  • xstream 1.4.1(继承自 smooks);
  • 抛弃 1.3.3(继承自 cxf);

另外,我读到 xstream 1.3 不能与 jettison 1.3.3 一起正常工作,但使用 xstream 1.3(不包括 pom 中的 xstream 1.4.1)工作正常,而使用 xstream 1.4.1 或专业时,我发现以下异常:

Caused by: java.lang.InstantiationError: java.util.Map$Entry
        at sun.reflect.GeneratedSerializationConstructorAccessor1.newInstance(Unknown Source) [:1.6.0_23]
        at java.lang.reflect.Constructor.newInstance(Constructor.java:513) [rt.jar:1.6.0_23]
        at com.thoughtworks.xstream.converters.reflection.Sun14ReflectionProvider.newInstance(Sun14ReflectionProvider.java:75) [xstream-1.4.1.jar:]
        at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.instantiateNewInstance(AbstractReflectionConverter.java:424) [xstream-1.4.1.jar:]
        at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:229) [xstream-1.4.1.jar:]
        at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72) [xstream-1.4.1.jar:]
        at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:65) [xstream-1.4.1.jar:]
        at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66) [xstream-1.4.1.jar:]
        at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:50) [xstream-1.4.1.jar:]
        at com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter.readItem(AbstractCollectionConverter.java:71) [xstream-1.4.1.jar:]
        at com.thoughtworks.xstream.converters.collections.MapConverter.putCurrentEntryIntoMap(MapConverter.java:85) [xstream-1.4.1.jar:]
        at com.thoughtworks.xstream.converters.collections.MapConverter.populateMap(MapConverter.java:77) [xstream-1.4.1.jar:]
        at com.thoughtworks.xstream.converters.collections.MapConverter.populateMap(MapConverter.java:71) [xstream-1.4.1.jar:]
        at com.thoughtworks.xstream.converters.collections.MapConverter.unmarshal(MapConverter.java:66) [xstream-1.4.1.jar:]
        at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72) [xstream-1.4.1.jar:]
        at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:65) [xstream-1.4.1.jar:]
        at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66) [xstream-1.4.1.jar:]
        at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:50) [xstream-1.4.1.jar:]
        at com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:134) [xstream-1.4.1.jar:]
        at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.unmarshal(AbstractTreeMarshallingStrategy.java:32) [xstream-1.4.1.jar:]
        at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1035) [xstream-1.4.1.jar:]
        at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1019) [xstream-1.4.1.jar:]
        at com.thoughtworks.xstream.XStream.fromXML(XStream.java:895) [xstream-1.4.1.jar:]
        at com.thoughtworks.xstream.XStream.fromXML(XStream.java:886) [xstream-1.4.1.jar:]
        at org.springframework.batch.core.repository.dao.XStreamExecutionContextStringSerializer.deserialize(XStreamExecutionContextStringSerializer.java:48) [spring-batch-core-2.1.9.RELEASE.jar:]
        at org.springframework.batch.core.repository.dao.JdbcExecutionContextDao$ExecutionContextRowMapper.mapRow(JdbcExecutionContextDao.java:222) [spring-batch-core-2.1.9.RELEASE.jar:]
        at org.springframework.batch.core.repository.dao.JdbcExecutionContextDao$ExecutionContextRowMapper.mapRow(JdbcExecutionContextDao.java:215) [spring-batch-core-2.1.9.RELEASE.jar:]
        at org.springframework.jdbc.core.RowMapperResultSetExtractor.extractData(RowMapperResultSetExtractor.java:92) [org.springframework.jdbc-3.2.1.RELEASE.jar:3.2.1.RELEASE]
        at org.springframework.jdbc.core.RowMapperResultSetExtractor.extractData(RowMapperResultSetExtractor.java:60) [org.springframework.jdbc-3.2.1.RELEASE.jar:3.2.1.RELEASE]
        at org.springframework.jdbc.core.JdbcTemplate$1.doInPreparedStatement(JdbcTemplate.java:649) [org.springframework.jdbc-3.2.1.RELEASE.jar:3.2.1.RELEASE]
        at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:587) [org.springframework.jdbc-3.2.1.RELEASE.jar:3.2.1.RELEASE]
        at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:637) [org.springframework.jdbc-3.2.1.RELEASE.jar:3.2.1.RELEASE]
        at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:666) [org.springframework.jdbc-3.2.1.RELEASE.jar:3.2.1.RELEASE]
        at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:674) [org.springframework.jdbc-3.2.1.RELEASE.jar:3.2.1.RELEASE]
        at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:714) [org.springframework.jdbc-3.2.1.RELEASE.jar:3.2.1.RELEASE]
        at org.springframework.jdbc.core.simple.SimpleJdbcTemplate.query(SimpleJdbcTemplate.java:202) [org.springframework.jdbc-3.2.1.RELEASE.jar:3.2.1.RELEASE]
        at org.springframework.jdbc.core.simple.SimpleJdbcTemplate.query(SimpleJdbcTemplate.java:209) [org.springframework.jdbc-3.2.1.RELEASE.jar:3.2.1.RELEASE]
        at org.springframework.batch.core.repository.dao.JdbcExecutionContextDao.getExecutionContext(JdbcExecutionContextDao.java:106) [spring-batch-core-2.1.9.RELEASE.jar:]

1)我看过代码,我可以配置XStreamExecutionContextStringSerializer来设置reflectionProvider = null(这样就不会使用Provider)?

2)还有其他解决方案可以解决我的问题吗?

谢谢

4

3 回答 3

4

我不可能更改 xstream 版本和 jettison 版本,因为它们是由其他组件(如 smooks)导入的。

一个可能的解决方案是创建两个不同的JBoss 模块并将它们一起使用。

所以,我找到了另一个解决方案:使用spring-batch 2.2.0.RELEASE,并org.springframework.batch.core.repository.dao.DefaultExecutionContextSerializer用作序列化程序而不是XStream

下面的配置:

<bean id="batchDefaultSerializer" class="org.springframework.batch.core.repository.dao.DefaultExecutionContextSerializer" />

<bean id="jobRepository" class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="transactionManager" ref="batchTransactionManager" />
    <property name="lobHandler" ref="defaultLobHandler" />
    <property name="serializer" ref="batchDefaultSerializer" />
</bean>       

<bean id="jobExplorer"      
      class="org.springframework.batch.core.explore.support.JobExplorerFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="serializer" ref="batchDefaultSerializer" />
</bean>

我测试了它,它工作正常,所以,我认为这是最好的解决方案。

于 2014-03-12T08:34:50.870 回答
3

由于 Jettison 1.2+ 与 XStream 不兼容,升级 XStream 会导致 Spring Batch 崩溃。这是最近发现但尚未解决的问题。您的问题的解决方案是使用 Jettison 1.2 和 XStream 1.4.7

于 2014-03-11T13:56:02.520 回答
3

我将 Spring Boot 1.4.0 与 Spring Batch 3.0.7 一起使用,并在使用 Netflix OSS 组件 b/c 他们使用 XStreams 1.4.2 的微服务时遇到了这个问题。

我也在使用 Java 配置而不是 XML。这是我想出的解决问题的方法:在@Configuration 类中:

   @Bean
   public ExecutionContextSerializer serializer()
   {
      return new Jackson2ExecutionContextStringSerializer();
   }

   @Bean
   @Autowired
   public JobRepository jobRepository( DataSource dataSource, 
                                       PlatformTransactionManager txManager ) throws Exception
   {
        JobRepositoryFactoryBean fac = new JobRepositoryFactoryBean();
        fac.setDataSource( dataSource );
        fac.setTransactionManager( txManager );
        fac.setSerializer( serializer() );
        fac.afterPropertiesSet();
        return fac.getObject();
   }

   @Bean
   @Autowired
   public JobExplorer jobExplorer( DataSource dataSource ) throws Exception
   {
      JobExplorerFactoryBean fac = new JobExplorerFactoryBean();
      fac.setDataSource( dataSource );
      fac.setSerializer( serializer() );
      fac.afterPropertiesSet();
      return fac.getObject();
   }

我使用 Postgres 作为后备存储,因此 DefaultExecutionContextSerializer 不起作用,因为它试图序列化二进制而不是 UTF-8 (JSON)。

于 2016-09-08T19:30:46.680 回答