从Spring批处理中的另一个xml导入Job

我有两个xmls,它有两个独立的Spring批处理作业 . 我想从第一个job steplistener(Bean名称“extractStepListener”)调用第二个作业 . 我已经在我的第一个(extract.xml)中导入了第二个(transform.xml),以便我可以引用该作业 . 当我尝试部署它时,我得到一个重复的作业例外 . 如果我在一个xml文件中定义了所有作业,它可以正常工作 .

extract.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:batch="http://www.springframework.org/schema/batch" 
    xmlns:util="http://www.springframework.org/schema/util"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/batch 
        http://www.springframework.org/schema/batch/spring-batch.xsd
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/util 
        http://www.springframework.org/schema/util/spring-util.xsd">

    <import resource="common.xml" />
    <import resource="transform.xml"/>

    <job id="extract" xmlns="http://www.springframework.org/schema/batch">
        <step id="cleanupWorkTables" next="productCategoryLoad">
            <tasklet ref="workTableDataCleanupTasklet"/>
        </step>
        <step id="productCategoryLoad" next="globalCatalogLoad">
            <tasklet>
                <chunk reader="productCategoryReader" writer="productCategoryWriter" commit-interval="500" />
            </tasklet>
        </step>
        <step id="globalCatalogLoad" next="validateProduct">
            <tasklet>
                <chunk reader="categoryReader" writer="categoryWriter" commit-interval="500" />
            </tasklet>
        </step>
        <step id="validateProduct">
            <tasklet>
                <chunk reader="productReader" processor="validateProductProcessor" writer="errorLogWriter" commit-interval="500" />
                <listeners>
                    <listener ref="extractStepListener" />
                </listeners>

            </tasklet>
        </step>
    </job>

    <bean id="errorLogWriter" class="org.springframework.batch.item.database.JdbcBatchItemWriter" scope="step">
        <property name="dataSource" ref="transformToolDataSource" />  
        <property name="sql">
            <value>
                <![CDATA[        
                    insert into error_log (JOB_EXECUTION_ID, JOB_TYPE, ERROR_TEXT, ISBN, LAST_UPDATED) 
                        values (:jobExecutionId, :jobType, :errorMessage, :isbn, :lastUpdated)  
                ]]>
            </value>
        </property>
        <property name="itemSqlParameterSourceProvider" ref="errorLogSqlParameterSourceProvider"/>
    </bean> 

    <bean id="productReader" class="org.springframework.batch.item.database.JdbcCursorItemReader" scope="step">
        <property name="dataSource" ref="transformToolDataSource" />
        <property name="sql" value="select p.isbn, p.isbn13, p.edition, p.copyright_year, p.marketing_title, p.list_price, p.net_price, pc.first_name, pc.last_name 
                    from product p, product_contributor pc 
                    where p.isbn = pc.isbn" />
        <property name="rowMapper" ref="productMapper"/>
        <property name="fetchSize" value="500"/>
    </bean>

    <bean id="validateProductProcessor" class="com.mheducation.unitas.extract.processor.ValidateProductProcessor">
        <property name="validator" ref="validator" />
    </bean> 

    <bean id="validator" class="com.mheducation.unitas.extract.validator.ProductValidator"/>

    <bean id="workTableDataCleanupTasklet" class="com.mheducation.unitas.extract.tasklet.WorkTableDataCleanupTasklet">
        <property name="queryList">
            <list>
                <value>Delete From PRODUCT</value>
                <value>Delete from Category</value>
                <value>Delete from Error_Log</value>
            </list>
        </property>
        <property name="jdbcTemplate" ref="jdbcTemplate" />
    </bean>

    <bean id="productCategoryReader" class="org.springframework.batch.item.database.JdbcCursorItemReader" scope="step">
        <property name="dataSource" ref="repMPDDataSource" />
        <property name="sql" value="select distinct p.division, p.isbn, p.copyright, pcx.division &quot;Cat Division&quot;, pcx.primary, c1.category_market_code &quot;Catalog&quot;, 
                    c1.category_1_id &quot;Lvl 1 ID&quot;, c1.description &quot;Lvl 1 Description&quot;, 
                    c2.category_2_id &quot;Lvl 2 ID&quot;, c2.description &quot;Lvl 2 Description&quot;, 
                    c3.category_3_id &quot;Lvl 3 ID&quot;, c3.description &quot;Lvl 3 Description&quot;, 
                    c4.category_4_id &quot;Lvl 4 ID&quot;, c4.description &quot;Lvl 4 Description&quot; 
                    from mpd.category_1 c1, mpd.category_2 c2,
                    mpd.category_3 c3, mpd.category_4 c4, mpd.product p, mpd.prod_cat_xref pcx, 
                    mpd.prod_publish_xref pubx, mpd.country_product_xref cpx 
                    where pcx.project_number = p.project_number
                    and p.division in ('MHHE', 'PCP')
                    and p.project_number = pubx.project_number
                    and pubx.publish_code in ('PKMP', 'PMHO')
                    and pubx.division = p.division
                    and p.project_number = cpx.project_number
                    and cpx.country_code = 'US'
                    and cpx.gtp_pub_status_code in ('IP-ACTIVE','GOP','NYP','OP','OSI', 'CAN', 'MD')    
                    and pcx.category_2_id = c2.category_2_id (+)
                    and c2.category_1_id = c1.category_1_id (+)
                    and c1.category_market_code = 'GHE'    
                    and pcx.category_3_id = c3.category_3_id (+)
                    and pcx.category_4_id = c4.category_4_id (+) order by p.isbn" />
        <property name="rowMapper" ref="productCategoryMapper"/>
        <property name="fetchSize" value="500"/>
    </bean>

    <bean id="productCategoryWriter" class="org.springframework.batch.item.database.JdbcBatchItemWriter" scope="step">
        <property name="dataSource" ref="transformToolDataSource" />  
        <property name="sql">
            <value>
                <![CDATA[        
                    insert into product_category (ISBN, CATALOG, PRIMARY, LEVEL_1_ID, LEVEL_1_DESCRIPTION, LEVEL_2_ID, LEVEL_2_DESCRIPTION, LEVEL_3_ID, LEVEL_3_DESCRIPTION, LEVEL_4_ID, LEVEL_4_DESCRIPTION) 
                        values (:isbn, :catalog, :primary, :level1Id, :level1Desc, :level2Id, :level2Desc, :level3Id, :level3Desc,:level4Id, :level4Desc)   
                ]]>
            </value>
        </property>
        <property name="itemSqlParameterSourceProvider" ref="productCategorySqlParameterSourceProvider"/>
    </bean>

    <bean id="categoryReader" class="org.springframework.batch.item.database.JdbcCursorItemReader" scope="step">
        <property name="dataSource" ref="repMPDDataSource" />
        <property name="sql" value="select c1.category_market_code &quot;Catalog&quot;,
                c1.category_1_id &quot;Lvl 1 ID&quot;, c1.description &quot;Lvl 1 Description&quot;, c1.sort_sequence &quot;Lvl 1 Sort Sequence&quot;,
                c2.category_2_id &quot;Lvl 2 ID&quot;, c2.description &quot;Lvl 2 Description&quot;, c2.sort_sequence &quot;Lvl 2 Sort Sequence&quot;,
                c3.category_3_id &quot;Lvl 3 ID&quot;, c3.description &quot;Lvl 3 Description&quot;, c3.sort_sequence &quot;Lvl 3 Sort Sequence&quot;,
                c4.category_4_id &quot;Lvl 4 ID&quot;, c4.description &quot;Lvl 4 Description&quot;, c4.sort_sequence &quot;Lvl 4 Sort Sequence&quot;
                from mpd.category_1 c1, mpd.category_2 c2,
                mpd.category_3 c3, mpd.category_4 c4
                where c1.category_1_id = c2.category_1_id (+)
                and c2.category_2_id = c3.category_2_id (+)
                and c3.category_3_id = c4.category_3_id (+)
                and c1.category_market_code = 'GHE'
                order by c1.description, c2.description, c3.description, c4.description" />
        <property name="rowMapper" ref="categoryMapper"/>
        <property name="fetchSize" value="500"/>
    </bean>

    <bean id="categoryWriter" class="org.springframework.batch.item.database.JdbcBatchItemWriter" scope="step">
        <property name="dataSource" ref="transformToolDataSource" />  
        <property name="sql">
            <value>
                <![CDATA[        
                    insert into category (CATALOG, LEVEL_1_ID, LEVEL_1_DESCRIPTION, LEVEL_1_SORT_SEQUENCE, LEVEL_2_ID, LEVEL_2_DESCRIPTION, LEVEL_2_SORT_SEQUENCE, LEVEL_3_ID, LEVEL_3_DESCRIPTION, LEVEL_3_SORT_SEQUENCE, LEVEL_4_ID, LEVEL_4_DESCRIPTION, LEVEL_4_SORT_SEQUENCE, LAST_UPDATED) 
                        values (:catalog, :level1Id, :level1Desc, :level1SortSequence, :level2Id, :level2Desc, :level2SortSequence, :level3Id, :level3Desc, :level3SortSequence, :level4Id, :level4Desc, :level4SortSequence, :lastUpdated) 
                ]]>
            </value>
        </property>
        <property name="itemSqlParameterSourceProvider" ref="categorySqlParameterSourceProvider"/>
    </bean> 

    <bean id="extractStepListener" class="com.mheducation.unitas.extract.listener.ExtractStepListener" >
        <property name="job" ref="transformationJob"/>
        <property name="jobLauncher" ref="jobLauncher"/>

    </bean>

</beans>

transform.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:batch="http://www.springframework.org/schema/batch" 
    xmlns:util="http://www.springframework.org/schema/util"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/batch 
        http://www.springframework.org/schema/batch/spring-batch.xsd
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/util 
        http://www.springframework.org/schema/util/spring-util.xsd">

    <import resource="common.xml" />

    <job id="transformationJob" xmlns="http://www.springframework.org/schema/batch">
        <step id="productTransform" next="categoryTransform">
            <tasklet>
                <chunk reader="transformProductReader" processor="transformProductProcesser" writer="transformProductWriter" commit-interval="5">
                </chunk>
            </tasklet>
        </step>
        <step id="categoryTransform">
            <tasklet>
                <chunk reader="transformCategoryReader"  writer="transformCategoryWriter" commit-interval="10">
                </chunk>
            </tasklet>
        </step>
     </job>

    <bean id="transformProductReader" class="org.springframework.batch.item.database.JdbcPagingItemReader" scope="step">
        <property name="dataSource" ref="transformToolDataSource" />
        <property name="queryProvider">
            <bean class="org.springframework.batch.item.database.support.SqlPagingQueryProviderFactoryBean">
                <property name="dataSource" ref="transformToolDataSource" />
                <property name="selectClause" value="SELECT ISBN,ISBN13,MASTER_ISBN,EDITION,
                                COPYRIGHT_YEAR,MARKETING_TITLE,TITLE_TYPE_CODE,PUBLICATION_STATUS_CODE,
                                SUBSCRIPTION_DURATION,SUBSCRIPTION_PERIOD,SPONSOR_CODE,PRODUCT_BRANDING,MARKET_CLASSIFICATION,PUBLICATION_DATE,PROJECTED_PUBLICATION_DATE,INSTRUCTOR_MATERIAL,
                                PRODUCT_USER,PRODUCT_USER_DESC,LANGUAGE,LANGUAGE_DESC,CORE_PRODUCT,SUPPLEMENT_PRODUCT,VOLUME,SUBSTITUTED_TO_ISBN,
                                AVAILABLE_INDIVIDUALLY,LIST_PRICE,NET_PRICE,COUNTRY_CODE,CURRENCY_CODE,PAGE_COUNT,TOC_PRELIMINARY_OR_FINAL,TABLE_OF_CONTENTS,
                                PUBLISHER_CODE,PUBLISHER_DESC,IMPRINT,IMPRINT_DESC,HE_PUBLISH_CODE,SHOP_PUBLISH_CODE,PREVIOUS_EDITION_ISBN,
                                DIVISION,MASTER,PACKAGE,PACKAGE_TYPE,ITEM_TYPE,DELIVERY_MEDIUM,FORMAT_CODE,PRODUCT_USAGE,VALID_PRODUCT,
                                FORMAT_TYPE_DESC,INSTRUCTOR_COMP,SCDF,
                                HEIGHT_FPS,THICKNESS_FPS,WIDTH_FPS,WEIGHT_FPS,HEIGHT_SI,THICKNESS_SI,WIDTH_SI,WEIGHT_SI,
                                LENGTH_UNIT_FPS,WEIGHT_UNIT_FPS,LENGTH_UNIT_SI,WEIGHT_UNIT_SI"/>
                <property name="fromClause" value="from PRODUCT" />
                <property name="whereClause" value="where VALID_PRODUCT='Y'" />
                <property name="sortKey" value="ISBN" />
            </bean>
        </property>
        <property name="pageSize" value="10" />
        <property name="rowMapper" ref="transformProductRowMapper"/>
    </bean>

    <bean id="transformProductRowMapper" class="com.mheducation.unitas.transform.mapper.TransformProductRowMapper" />

    <bean id="transformProductProcesser" class="com.mheducation.unitas.transform.processor.TransformProductProcessor" >
        <property name="transformProcessDAO" ref="transformProcessDAO"/>
        <property name="transformProcessHelper" ref="transformProcessHelper"/>  
    </bean>  

    <bean id="transformProductWriter" class="com.mheducation.unitas.transform.writer.TransformProductWriter">
        <property name="marshaller" ref="jaxbMarshaller"/>
        <property name="transformProcessHelper" ref="transformProcessHelper"/>
        <property name="fileLocation" value = "${TRANSFORM_OUTPUT_XML_DIRECTORY}"/> 
    </bean>  

    <bean id="transformProcessDAO" class="com.mheducation.unitas.transform.dao.impl.TransformProcessDAOImpl">
         <property name="jdbcTemplate" ref="jdbcTemplate" /> 
    </bean>

    <bean id="transformProcessHelper" class="com.mheducation.unitas.transform.helper.TransformProcessHelper">
    </bean>

    <bean id="jaxbMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
     <property name="classesToBeBound">
      <list>
        <value>com.mheducation.unitas.transform.jaxb.product.Categories</value>
        <value>com.mheducation.unitas.transform.jaxb.product.Category</value>
        <value>com.mheducation.unitas.transform.jaxb.product.CategoryHierarchies</value>
        <value>com.mheducation.unitas.transform.jaxb.product.CategoryHierarchy</value>
        <value>com.mheducation.unitas.transform.jaxb.product.DigitalProduct</value>
        <value>com.mheducation.unitas.transform.jaxb.product.DigitalProducts</value>
        <value>com.mheducation.unitas.transform.jaxb.product.ObjectFactory</value>
        <value>com.mheducation.unitas.transform.jaxb.product.Package</value>
        <value>com.mheducation.unitas.transform.jaxb.product.PackageComponents</value>
        <value>com.mheducation.unitas.transform.jaxb.product.Packages</value>
        <value>com.mheducation.unitas.transform.jaxb.product.PrintProduct</value>
        <value>com.mheducation.unitas.transform.jaxb.product.PrintProducts</value>
        <value>com.mheducation.unitas.transform.jaxb.product.Product</value>
        <value>com.mheducation.unitas.transform.jaxb.product.ProductCategoryAssociations</value>
        <value>com.mheducation.unitas.transform.jaxb.product.ProductComponents</value>
        <value>com.mheducation.unitas.transform.jaxb.product.ProductContributor</value>
        <value>com.mheducation.unitas.transform.jaxb.product.ProductContributors</value>
        <value>com.mheducation.unitas.transform.jaxb.product.ProductFeature</value>
        <value>com.mheducation.unitas.transform.jaxb.product.ProductFeatures</value>
        <value>com.mheducation.unitas.transform.jaxb.product.Products</value>
        <value>com.mheducation.unitas.transform.jaxb.product.ProductText</value>
        <value>com.mheducation.unitas.transform.jaxb.product.ProductTexts</value>
        <value>com.mheducation.unitas.transform.jaxb.product.ProductUrl</value>
        <value>com.mheducation.unitas.transform.jaxb.product.ProductUrls</value>
        <value>com.mheducation.unitas.transform.jaxb.product.RelatedProducts</value>
        <value>com.mheducation.unitas.transform.jaxb.product.SubPackages</value>
        <value>com.mheducation.unitas.transform.jaxb.product.CategoryHierarchiesType</value>
      </list>
    </property>
    </bean>

    <bean id="transformCategoryReader" class="org.springframework.batch.item.database.JdbcCursorItemReader" >
        <property name="dataSource" ref="transformToolDataSource" />
        <property name="sql" value="SELECT CATALOG,LEVEL_1_ID,LEVEL_1_DESCRIPTION,LEVEL_1_SORT_SEQUENCE,LEVEL_2_ID,
                                                            LEVEL_2_DESCRIPTION,LEVEL_2_SORT_SEQUENCE,LEVEL_3_ID,LEVEL_3_DESCRIPTION,
                                                            LEVEL_3_SORT_SEQUENCE,LEVEL_4_ID,LEVEL_4_DESCRIPTION,LEVEL_4_SORT_SEQUENCE
                                                            FROM CATEGORY"/>

        <property name="rowMapper" ref="transformCategoryRowMapper"/>
    </bean>

    <bean id="transformCategoryRowMapper" class="com.mheducation.unitas.transform.mapper.TransformCategoryRowMapper" />

    <bean id="transformCategoryWriter" class="com.mheducation.unitas.transform.writer.TransformCategoryWriter">
        <property name="marshaller" ref="jaxbCategoryMarshaller"/>
        <property name="fileLocation" value = "${TRANSFORM_OUTPUT_XML_DIRECTORY}"/>
    </bean> 

    <bean id="jaxbCategoryMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
     <property name="classesToBeBound">
      <list>
        <value>com.mheducation.unitas.transform.jaxb.category.Categories</value>
        <value>com.mheducation.unitas.transform.jaxb.category.Category</value>
        <value>com.mheducation.unitas.transform.jaxb.category.ObjectFactory</value>
      </list>
    </property>
    </bean>    

</beans>

Common xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:batch="http://www.springframework.org/schema/batch" 
    xmlns:util="http://www.springframework.org/schema/util"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/batch 
        http://www.springframework.org/schema/batch/spring-batch.xsd
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/util 
        http://www.springframework.org/schema/util/spring-util.xsd">

    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
     <constructor-arg>  
            <ref bean="transformToolDataSource" />  
        </constructor-arg>  
    </bean>

</beans>

部署异常

SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
java.lang.IllegalStateException: org.springframework.batch.core.configuration.DuplicateJobException: A job configuration with this name [transformationJob] was already registered
    at org.springframework.batch.core.configuration.support.AutomaticJobRegistrar.start(AutomaticJobRegistrar.java:176)
    at org.springframework.batch.core.configuration.support.AutomaticJobRegistrar.onApplicationEvent(AutomaticJobRegistrar.java:139)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:98)
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:333)
    at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:776)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:485)
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:403)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4973)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5467)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:632)
    at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:1083)
    at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:553)
    at org.apache.catalina.startup.HostConfig.check(HostConfig.java:1671)
    at sun.reflect.GeneratedMethodAccessor101.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:301)
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
    at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
    at org.apache.catalina.manager.ManagerServlet.check(ManagerServlet.java:1485)
    at org.apache.catalina.manager.HTMLManagerServlet.upload(HTMLManagerServlet.java:286)
    at org.apache.catalina.manager.HTMLManagerServlet.doPost(HTMLManagerServlet.java:206)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:646)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.filters.CsrfPreventionFilter.doFilter(CsrfPreventionFilter.java:213)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.filters.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:108)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:610)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.batch.core.configuration.DuplicateJobException: A job configuration with this name [transformationJob] was already registered
    at org.springframework.batch.core.configuration.support.MapJobRegistry.register(MapJobRegistry.java:51)
    at org.springframework.batch.core.configuration.support.DefaultJobLoader.doRegister(DefaultJobLoader.java:250)
    at org.springframework.batch.core.configuration.support.DefaultJobLoader.doLoad(DefaultJobLoader.java:185)
    at org.springframework.batch.core.configuration.support.DefaultJobLoader.load(DefaultJobLoader.java:147)
    at org.springframework.batch.core.configuration.support.AutomaticJobRegistrar.start(AutomaticJobRegistrar.java:173)

transformation-tool-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <context:property-placeholder location="classpath*:**/*.properties"/>

    <context:component-scan base-package="com.mheducation.unitas" />
    <mvc:annotation-driven/>
        <!--    
    <bean id="liquibase" class="liquibase.integration.spring.SpringLiquibase">
        <property name="dataSource" ref="transformToolDataSource" />
        <property name="changeLog" value="classpath:changelogs/dbchange-log-master.xml" />
        <property name="defaultSchema" value="TRANSFORMATION_TOOL" />
     </bean>
     -->

     <bean id="config" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
        <property name="location" value="classpath:properties/TransformToolConfig.properties"/>
     </bean>

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
      <property name="propertiesArray">
        <list>
          <ref bean="config"/>
        </list>
      </property>
    </bean>

    <bean id="jobRepository"
        class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean">
        <property name="transactionManager" ref="transactionManager" />
    </bean>

    <bean id="jobLauncher"
        class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
        <property name="jobRepository" ref="jobRepository" />
    </bean>

</beans>

web.xml

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath:META-INF/spring/batch/webapp-config.xml
            classpath:META-INF/spring/jdbc-config.xml
            classpath:META-INF/spring/transformation-tool-context.xml
        </param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <filter>
        <filter-name>shallowEtagHeaderFilter</filter-name>
        <filter-class>org.springframework.web.filter.ShallowEtagHeaderFilter</filter-class>
    </filter>

    <filter>
        <filter-name>hiddenHttpMethodFilter</filter-name>
        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>shallowEtagHeaderFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <filter-mapping>
        <filter-name>hiddenHttpMethodFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <servlet>
        <servlet-name>Batch Servlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:META-INF/spring/batch/servlet-config.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>Batch Servlet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>

</web-app>

回答(1)

2 years ago

我在transformation-tool-context.xml中注册了MapJobRegistry和BeanPostProcessor,并使用Spring批处理调度程序来定位和运行作业 .

以下是摘录

添加了以下bean

transformation-tool-context.xml

<bean id="jobRegistry" class="org.spr...MapJobRegistry" />

<bean id="jobRegistryBeanPostProcessor" class="org.springframework.batch.core.configuration.support.JobRegistryBeanPostP‌​rocessor">
    <property name="jobRegistry" ref="jobRegistry"/>
</bean>

添加了以下Spring任务调度程序(为简洁起见,忽略xmlns)

transformation-tool-scheduler.xml

<task:scheduled-tasks>
        <task:scheduled ref="runScheduler" method="run" cron="*/5 * * * * *" />
   </task:scheduled-tasks>

RunScheduler.java

@Component
public class ExtractStepListener  {

    @Autowired
    private JobLauncher jobLauncher;
    @Autowired
    private JobLocator jobRegistry;

    public void run() {

        try {
                JobParameters param = new JobParametersBuilder().toJobParameters();
                jobLauncher.run(jobRegistry.getJob("extract"), param);
                jobLauncher.run(jobRegistry.getJob("transformationJob"), param);

            } catch (Exception e) {
            System.out.println("Error occured while launching transform");
            e.printStackTrace();
        }

    }   
}