I have a spring batch application which has the property file batch-default.properties set up as
batch.job.configuration.file.dir=target/config
Now this application works well on my local machine even though i do not have any such directory but when i try to deploy the same on my integration server i am getting the error:
Cannot resolve reference to bean 'org.springframework.integration.config.SourcePollingChannelAdapterFactoryBean#0.source' while setting bean property 'source'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.integration.config.SourcePollingChannelAdapterFactoryBean#0.source': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalArgumentException: Source directory [target/config] does not exist.
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:334)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:108)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1417)
Has anyone faced any similar problem?
Any help appriciated here.
-Vaibhav
We had a similar issue on our test server. Looks like a problem with file permissions, i.e. Spring Batch Admin tries to create a directory structure for "target/config", but the user is not allowed to create the directories.
This is the chain causing the problem:
META-INF/spring/batch/bootstrap/integration/configuration-context.xml
contains the definition of a file poller refering to the property:
<file:inbound-channel-adapter directory="${batch.job.configuration.file.dir}" channel="job-configuration-files"
filename-pattern=".*\.xml">
<poller max-messages-per-poll="1" cron="5/1 * * * * *" />
</file:inbound-channel-adapter>
Checking the documentation of the inbound-channel-adapter reveals the following (spring-integration-file-2.1.xsd):
<xsd:attribute name="directory" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation><![CDATA[Specifies the input directory (The directory to poll from) e.g.:
directory="file:/absolute/input" or directory="file:relative/input"]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
and (!)
<xsd:attribute name="auto-create-directory" type="xsd:string" default="true">
<xsd:annotation>
<xsd:documentation>
Specify whether to automatically create the source directory if it does not yet exist when this
adapter is being initialized. The default value is 'true'. If set to 'false' and the directory
does not exist upon initialization, an Exception will be thrown.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
So, as an result, auto-create-directory
is true and Spring is trying to create the (relative) directory structure somewhere on the shell path of your server.
For the error message, checking the java class org.springframework.integration.file.FileReadingMessageSource
gives the explanation:
if (!this.directory.exists() && this.autoCreateDirectory) {
this.directory.mkdirs();
}
Assert.isTrue(this.directory.exists(),
"Source directory [" + directory + "] does not exist.");
The javadoc of java.io.File.mkdirs()
says:
public boolean mkdirs()
Creates the directory named by this abstract pathname, including any necessary but nonexistent parent directories. Note that if this operation fails it may have succeeded in creating some of the necessary parent directories.
Returns:
true if and only if the directory was created, along with all necessary parent directories; false otherwise
So what happens is, the mkdirs() returns "false" because he couldn't create the directory. The following exists() will also return "false" returning the error messsage as stated in the original post.
You can workaround be setting the parameter to an existing and writeable directory like "/tmp" using an absolute path. Unfortunately I have no idea how this spring batch feature should work, if you store your job definitions on a classpath; it would make more sense not to use a file poller but to use a "classpath-aware" file poller...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With