load external config file in spring batch admin

女生的网名这么多〃 提交于 2019-12-03 22:32:48

问题


I downloaded the spring batch admin application in the github repo and I imported it in eclipse. it works perfectly.

Then, I asked myself how to import an external config file into the application that I can use in my job definition class.

I tried this :

VM Arguments

-Dspring.config.location=C:/path/to/config/file/application.properties

Job configuration

src/main/java
org.springframework.batch.admin.sample.job
-------------------------------------------

@Configuration
public class JobConfiguration {

    //I try to import this properties from an external config file.
    @Value("${folder.input.files}") 
    private String pathToFiles;

    @Autowired
    public JobBuilderFactory jobBuilderFactory;

    @Autowired
    public StepBuilderFactory stepBuilderFactory;

    @Bean
    @JobScope
    public ExampleItemReader itemReader() {
        return new ExampleItemReader();
    }

    @Bean
    @StepScope
    public ExampleItemWriter itemWriter(@Value("#{jobParameters[fail]}") Boolean fail) {
        ExampleItemWriter itemWriter = new ExampleItemWriter();
        itemWriter.setFail(fail);
        return itemWriter;
    }

    @Bean
    public Step step1() {
        return stepBuilderFactory.get("step1")
                .<String, Object>chunk(5)
                .reader(itemReader())
                .writer(itemWriter(null))
                .build();
    }

    @Bean
    public Job javaJob() {
        return jobBuilderFactory.get("javaJob")
                .start(step1())
                .build();
    }
}

XML configuration

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

<description><![CDATA[
  A convenient aggregating config file for running the jobs in this project
  from the command line instead of from the web application.  E.g.

  $ MAVEN_OPTS="-Dbatch.jdbc.url=jdbc:hsqldb:hsql://localhost:9005/samples -Dbatch.data.source.init=false" \
    mvn exec:java -Dexec.classpathScope=runtime \
    -Dexec.mainClass=org.springframework.batch.core.launch.support.CommandLineJobRunner \
    -Dexec.args="classpath:launch-context.xml job1 fail=false run.id=1"


  ]]>
</description>

<import resource="classpath*:/META-INF/spring/batch/bootstrap/**/*.xml" />
<import resource="classpath*:/META-INF/spring/batch/override/**/*.xml" />

<bean id="jobLauncherTaskExecutor" class="org.springframework.core.task.SyncTaskExecutor"/>

<!-- Try to add my external config file -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <list>
            <value>classpath:file:///${spring.config.location}</value>
        </list>
    </property>
    <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
    <property name="ignoreResourceNotFound" value="true" />
    <property name="ignoreUnresolvablePlaceholders" value="false" />
    <property name="order" value="1" />
</bean>


</beans>

Stack trace when I launch the app with tomcat 7

18:54:38,528 ERROR localhost-startStop-1 context.ContextLoader:331 - Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jobConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private java.lang.String org.springframework.batch.admin.sample.job.JobConfiguration.pathToFiles; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'folder.input.files' in string value "${folder.input.files}"
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1204)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:538)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:229)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:762)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
    at org.springframework.batch.core.configuration.support.GenericApplicationContextFactory$ResourceAnnotationApplicationContext.<init>(GenericApplicationContextFactory.java:209)
    at org.springframework.batch.core.configuration.support.GenericApplicationContextFactory.createApplicationContext(GenericApplicationContextFactory.java:70)
    at org.springframework.batch.core.configuration.support.AbstractApplicationContextFactory.createApplicationContext(AbstractApplicationContextFactory.java:172)
    at org.springframework.batch.core.configuration.support.DefaultJobLoader.doLoad(DefaultJobLoader.java:154)
    at org.springframework.batch.core.configuration.support.DefaultJobLoader.load(DefaultJobLoader.java:147)
    at org.springframework.batch.core.configuration.support.AutomaticJobRegistrar.start(AutomaticJobRegistrar.java:173)
    at org.springframework.batch.core.configuration.support.AutomaticJobRegistrar.onApplicationEvent(AutomaticJobRegistrar.java:139)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:151)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:128)
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:331)
    at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:773)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:483)
    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:4939)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5434)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private java.lang.String org.springframework.batch.admin.sample.job.JobConfiguration.pathToFiles; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'folder.input.files' in string value "${folder.input.files}"
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:555)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
    ... 34 more
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'folder.input.files' in string value "${folder.input.files}"
    at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:174)
    at org.springframework.util.PropertyPlaceholderHelper.replacePlaceholders(PropertyPlaceholderHelper.java:126)
    at org.springframework.beans.factory.config.PropertyPlaceholderConfigurer$PlaceholderResolvingStringValueResolver.resolveStringValue(PropertyPlaceholderConfigurer.java:259)
    at org.springframework.beans.factory.support.AbstractBeanFactory.resolveEmbeddedValue(AbstractBeanFactory.java:800)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:962)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:949)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:527)
    ... 36 more

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <artifactId>spring-batch-admin-sample</artifactId>
    <description>A sample web application (WAR project) for Spring Batch Admin console.</description>
    <parent>
        <artifactId>spring-batch-admin-parent</artifactId>
        <groupId>org.springframework.batch</groupId>
        <version>2.0.0.BUILD-SNAPSHOT</version>
        <relativePath>../spring-batch-admin-parent</relativePath>
    </parent>
    <packaging>war</packaging>
    <name>Web Sample</name>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
        </dependency>
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
        </dependency>
        <dependency>
            <groupId>commons-collections</groupId>
            <artifactId>commons-collections</artifactId>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
        </dependency>
        <dependency>
            <groupId>org.hsqldb</groupId>
            <artifactId>hsqldb</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.batch</groupId>
            <artifactId>spring-batch-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.batch</groupId>
            <artifactId>spring-batch-infrastructure</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.batch</groupId>
            <artifactId>spring-batch-admin-manager</artifactId>
            <version>2.0.0.BUILD-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.batch</groupId>
            <artifactId>spring-batch-admin-resources</artifactId>
            <version>2.0.0.BUILD-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-all</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.mortbay.jetty</groupId>
                <artifactId>maven-jetty-plugin</artifactId>
                <configuration>
                    <contextPath>/spring-batch-admin-sample</contextPath>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-deploy-plugin</artifactId>
                <configuration>
                    <skip>true</skip>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Maven Milestone Repository</name>
            <url>http://s3.amazonaws.com/maven.springframework.org/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>
</project>

I tried this post and much more but without success.

I use exactly the same files and the same configuration than the spring batch admin github project.

Can someone tell me how to add the external configuration file to spring batch admin?


回答1:


Spring batch admin searches configurations in specific paths.This page explains from which paths it loads resources:

<import resource="classpath*:/META-INF/spring/batch/bootstrap/**/*.xml"/>
<import resource="classpath*:/META-INF/spring/batch/override/**/*.xml"/>

Note that the "override" location has no files in it in Spring Batch Admin distribution. This is a placeholder for users to add their own content.

We managed to load external properties files placing xml configuration file under src/main/resources/META-INF/spring/batch/override/manager/env-context.xml which looks like this:

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

    <!-- Use this to set additional properties on beans at run time -->
    <bean id="placeholderProperties"
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:/org/springframework/batch/admin/bootstrap/batch.properties</value>
                <value>classpath:batch-default.properties</value>
                <value>classpath:batch-${ENVIRONMENT:hsql}.properties</value>
                <value>classpath:batch-${ENVIRONMENT:mysql}.properties</value>
                <!-- here we load properties from external config folder -->
                <value>file:${spring.file.location}</value>
             </list>
        </property>
        <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
        <property name="ignoreResourceNotFound" value="false" />
        <property name="ignoreUnresolvablePlaceholders" value="false" />
        <property name="order" value="1" />
    </bean>
</beans>



回答2:


Under main folder of spring-batch-admin template, there are three folders - java, resources and webapp. Under resources there are some property files and META-INF folder. within META-INF there are two folders - batch and servlet.

Here If I want to add new property file "batch.properties" under resources and want to refer the property values from configuration (xml) files from "META-INF/batch/*.xml" in addition to the properties from spring-batch-admin-manager-1.0.0.M1.jar, 1. where to add below entries

  1. Where to keep "env-context.xml". Under which folders, coz in "src/main/resources/META-INF" i can see only one folder batch.

  2. I tried to create "spring/batch/override/manager/env-context.xml" under "src/main/resources/META-INF" but not able to read the property file entries.

If you provide your working application folder structure will help me a lot.




回答3:


You can put your env-context.xml file on spring/batch/servlet/override/env-context.xml folder.



来源:https://stackoverflow.com/questions/30465345/load-external-config-file-in-spring-batch-admin

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!